#include "PackagePart.h"
#include "base/core/gamemath.h"
#include "Scene/SceneMgr.h"
#include "base/core/log.h"
#include "base/core/random.h"
#include "base/core/com_define.h"
#include "Common/TableData/ItemItemCfg.h"
#include "Common/TableData/EquipEquipCfg.h"
#include "Common/TableData/EquipStrengthenCfg.h"
#include "Common/TableData/EquipRefineCfg.h"
#include "Common/TableData/ConstantConstantCfg.h"
#include "Common/TableData/SkillSkillCfg.h"
#include "Common/TableData/ComposeComposeCfg.h"
#include "Common/TableData/EquipSuitCfg.h"
#include "Common/TableData/EquipFashionCfg.h"
#include "Common/AttrMgr/AttrMgr.h"
#include "Character/drop/DropMgr.h"
#include "ProtoBuffer/AllProtocol.h"
#include "Common/TableData/RoleBornCfg.h"
#include "Common/Utility/AccountUtility.h"
#include "Character/Player.h"
#include "Common/TableDataEx/ItemCfg.h"
#include "Duplicate/DuplicateMgr.h"
#include "Character/TreasurePart.h"
#include "Common/TableDataEx/EquipCfg.h"
#include "Character/CreatureMgr.h"
#include "Common/EventDefine.h"
#include "Character/SkillPart.h"
#include "Character/BuffPart.h"
#include "ServerModule/LogicActivityModule.h"
#include "Item/ItemUseMgr.h"
#include "Character/horse/HorsePart.h"
#include "Character/welfare/OperateWelfarePart.h"
#include "Common/OperateLimitDefine.h"
#include <functional>
#include <algorithm>
using namespace std;


namespace
{
	//背包总格子数量
	static const uint16_t s_totalPackageGrid = PACKAGE_MAX_GRID_NUM + 1;
	//背包保留的格子数量
	static const uint16_t s_packageReserveGrid = PACKAGE_RESERVE_GRID_NUM;
	//背包格子起始索引
	static const uint16_t s_packageStartIdx = 1;
	//背包格子结束索引
	static const uint16_t s_packageEndIdx = s_totalPackageGrid-1;
	//任务标签页初始格子索引
	static const uint16_t s_packageTaskStartIdx = s_totalPackageGrid + s_packageReserveGrid + 1;
	//任务标签页最大格子数量
	static const uint16_t s_totalPackageTaskGrid = PACKAGE_MAX_TASK_GRID_NUM;
	//任务标签页结束格子索引
	static const uint16_t s_packageTaskEndIdx = s_packageTaskStartIdx + s_totalPackageTaskGrid - 1;
	//所有背包的最大容量
	static const uint16_t s_allPackageCapacity = s_packageTaskEndIdx + 1;


	static const uint32_t s_day_total_min = 24 * 60;
	static const uint16_t s_totalStorageGrid = STORAGE_MAX_GRID_NUM + 1;
};


PackagePart::PackagePart() :m_nLastSortTime(0), m_nExpandNum(0)
{
	m_mapItemCd.clear();
	m_vecItems.clear();
	m_vecPlayerFashion.clear();
	//
	m_nOpenGrid = PACKAGE_INIT_GRID_NUM;
	m_vecItems.resize(s_allPackageCapacity, nullptr);
	MMO_ASSERT(m_vecItems.size() == s_allPackageCapacity);
	//
	m_vecPlayerEquip.resize(EEquipPos_limit, nullptr);
	m_vecPlayerGodEquip.resize(EEquipPos_limit, nullptr);
	m_vecEquipSlot.resize(EEquipPos_limit, EquipSlot());
	for (uint16_t pos = EEquipPos_none; pos != EEquipPos_limit; pos++)
		m_vecEquipSlot[pos].m_nIndex = pos;
	//仓库
	m_vecStorage.clear();
	m_storageExpand = 0;
	m_lastStorageSort = 0;
	m_vecStorage.resize(s_totalStorageGrid, nullptr);
	//

	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_PACKAGE_INFO, &PackagePart::ItemInfo));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_PACKAGE_SORT, &PackagePart::ItemSort));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_PACKAGE_SELL, &PackagePart::ItemSell));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_PACKAGE_USE, &PackagePart::ItemUse));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_PLAYER_PICKUP_DROP, &PackagePart::PickupDrop));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_PLAYER_EQUIP_INFO, &PackagePart::EquipInfo));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_PLAYER_EQUIP_DRESS, &PackagePart::EquipDress));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_PLAYER_EQUIP_UNDRESS, &PackagePart::EquipUnDress));
	//m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_PLAYER_EQUIP_ONEKEY_DRESS, &PackagePart::EquipOneKeyDress));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_EQUIP_ONEKEY_STREN, &PackagePart::EquipOneKeyStren));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_EQUIP_STREN, &PackagePart::EquipStren));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_EQUIP_REFINE, &PackagePart::EquipRefine));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_EQUIP_IDENTIFY, &PackagePart::EquipIdentify));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_EQUIP_SHOW_SELECT, &PackagePart::EquipSelect));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_EQUIP_INLAY, &PackagePart::StoneInlay));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_EQUIP_TAKEOFF, &PackagePart::StoneTakeoff));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_EQUIP_COMPOSE, &PackagePart::StoneCompose));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_EQUIP_DECOMPOSE, &PackagePart::EquipDecompose));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_EQUIP_COMPOSE_MATERIAL, &PackagePart::MaterialCompose));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_PACKAGE_CD_INFO, &PackagePart::CoolInfo));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_PACKAGE_UP_OPERATE, &PackagePart::RuneUp));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_PACKAGE_DOWN_OPERATE, &PackagePart::RuneDown));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_FASHION_DRESS, &PackagePart::DressFashion));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_FASHION_UNDRESS, &PackagePart::UnDressFashion));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_STAR_SOUL_MARK, &PackagePart::StarSoulMark));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_STAR_SOUL_RESP, &PackagePart::StarSoulResp));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_REBUY_BACK, &PackagePart::RebuyBack));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_DELETE_GOD_EQUIP, &PackagePart::DelGodEquip));

	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_STORAGE_INFO, &PackagePart::StorageInfo));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_STORAGE_SORT, &PackagePart::StorageSort));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_LOGIC_STORAGE_OPERATE, &PackagePart::StorageOperate));
}

PackagePart::~PackagePart()
{
}

bool PackagePart::Init(Creature *pMaster, uint32_t partType, CharacterDBInfo* pCharacterDB /* = nullptr */)
{
	Part::Init(pMaster, partType);


	//后期对玩家加判断
	if (pCharacterDB)
	{
		if (pCharacterDB->has_itemdata())
		{
			const CharacterDBPackageData &protoPackage = pCharacterDB->itemdata();
			m_nExpandNum = (uint16_t)protoPackage.expand_num();
			m_nOpenGrid += m_nExpandNum;
			
			uint16_t allSize = (uint16_t)protoPackage.all_size();
			for (uint16_t h = 0; h < allSize; ++h)
			{
				uint8_t byType = EItemType_common;
				const ItemProtoInfo &protoItem = protoPackage.all(h);
				const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(protoItem.item_id());
				if (nullptr == pItemCfg)
				{
					const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(protoItem.item_id());
					if (nullptr == pEquipCfg)
					{
						LogErrFmtPrint("[logic] PackagePart::Init..nullptr == pEquipCfg....itemid:%u ", protoItem.item_id());
						continue;
					}
					byType = EItemType_equip;
				}
				CItemBase *pItem = g_GetItemMgr()->MakeItemObj(byType);
				if (nullptr != pItem)
				{
					if (!pItem->SetItemProto(protoItem))
					{
						LogErrFmtPrint("[logic] PackagePart::Init 33, SetItemProto failed....index:%d, item_id:%u,num:%d,bind:%d..", protoItem.index(), protoItem.item_id(), protoItem.item_num(), protoItem.bind());
						g_GetItemMgr()->FreeItemObj(pItem);
					}
					else
					{
						if (!SetItemByIndex(pItem->GetIndex(), pItem))
						{
							LogErrFmtPrint("[logic] PackagePart::Init 44, SetItemByIndex failed....index:%d, item_id:%u,num:%d,bind:%d..", protoItem.index(), protoItem.item_id(), protoItem.item_num(), protoItem.bind());
							g_GetItemMgr()->FreeItemObj(pItem);
						}
					}
				}
				else
				{
					MMOLOG_FMT_ERROR("[logic] PackagePart::Init  , nullptr == pItem...");
				}
			}

			uint16_t ntaskSize = (uint16_t)protoPackage.task_size();
			for (uint16_t m = 0; m < ntaskSize; ++m)
			{
				const ItemProtoInfo &protoItem = protoPackage.task(m);
				const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(protoItem.item_id());
				if (nullptr != pItemCfg)
				{
					CItemBase *pItem = g_GetItemMgr()->MakeItemObj(EItemType_common);
					if (nullptr != pItem)
					{
						if (!pItem->SetItemProto(protoItem))
						{
							LogErrFmtPrint("[logic] PackagePart::Init 33, item SetItemProto failed....index:%d, item_id:%u,num:%d,bind:%d..", protoItem.index(), protoItem.item_id(), protoItem.item_num(), protoItem.bind());
							g_GetItemMgr()->FreeItemObj(pItem);
						}
						else
						{
							if (!SetItemByIndex(pItem->GetIndex(), pItem))
							{
								LogErrFmtPrint("[logic] PackagePart::Init 44, item SetItemByIndex failed....index:%d, item_id:%u,num:%d,bind:%d..", protoItem.index(), protoItem.item_id(), protoItem.item_num(), protoItem.bind());
								g_GetItemMgr()->FreeItemObj(pItem);
							}
						}
					}
					else
					{
						MMOLOG_FMT_ERROR("[logic] PackagePart::Init  , nullptr == pItem...");
					}
				}
				else
				{
					LogErrFmtPrint("[logic] PackagePart::Init..nullptr == pItemCfg 222....itemid:%u ", protoItem.item_id());
				}

			}


			//cd
			int32_t cdSize = protoPackage.cd_size();
			for (int32_t i = 0; i < cdSize; ++i)
			{
				const PackageCdDBProto &protoCd = protoPackage.cd(i);
				m_mapItemCd[protoCd.itemid_or_groupid()] = protoCd.start_cd();
			}


			//storage
			if (protoPackage.has_storage())
			{
				const CharacterDBStorageData protoStorage = protoPackage.storage();
				m_storageExpand = protoStorage.expand_num();
				int32_t storageSize = protoStorage.item_lst_size();
				for (int32_t j = 0; j < storageSize; ++j)
				{
					const ItemProtoInfo &protoItem = protoStorage.item_lst(j);
					CItemBase *pItem = nullptr;
					int8_t byType = EItemType_common;
					const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(protoItem.item_id());
					if (nullptr == pItemCfg)
					{
						const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(protoItem.item_id());
						if (nullptr == pEquipCfg)
						{
							MMOLOG_FMT_ERROR("[logic] PackagePart::Init  ,storage nullptr == pEquipCfg...itemid:%u ", protoItem.item_id());
							continue;
						}
						byType = EItemType_equip;
					}
					pItem = g_GetItemMgr()->MakeItemObj(byType);
					if (nullptr == pItem)
					{
						MMOLOG_FMT_ERROR("[logic] PackagePart::Init  ,storage nullptr == pItem...itemid:%u ", protoItem.item_id());
						continue;
					}
					if (!pItem->SetItemProto(protoItem))
					{
						LogErrFmtPrint("[logic] PackagePart::Init ,storage item SetItemProto failed....index:%d, item_id:%u,num:%d,bind:%d..", protoItem.index(), protoItem.item_id(), protoItem.item_num(), protoItem.bind());
						g_GetItemMgr()->FreeItemObj(pItem);
						continue;
					}
					if (!SetStorageItemByIndex(pItem->GetIndex(), pItem))
					{
						LogErrFmtPrint("[logic] PackagePart::Init ,storage item SetItemByIndex failed....index:%d, item_id:%u,num:%d,bind:%d..", protoItem.index(), protoItem.item_id(), protoItem.item_num(), protoItem.bind());
						g_GetItemMgr()->FreeItemObj(pItem);
						continue;
					}
				}
				
			}


		} // end of if (pCharacterDB->has_itemdata())

		
		if (pCharacterDB->has_equipdata())
		{
			const CharacterDBEquipData &protoEquip = pCharacterDB->equipdata();
			m_equipFacade.showType = (EEquipType)protoEquip.equip_type();
			uint16_t nequipSize = (uint16_t)protoEquip.equip_size();
			for (uint16_t k = 0; k < nequipSize; ++k)
			{
				const ItemProtoInfo &protoItem = protoEquip.equip(k);
				CItemBase *pItem = g_GetItemMgr()->MakeItemObj(EItemType_equip);
				if (nullptr != pItem)
				{
					if (!pItem->SetItemProto(protoItem))
					{
						LogErrFmtPrint("[logic] PackagePart::Init 55, item SetItemProto failed....index:%d, item_id:%u,num:%d,bind:%d..", protoItem.index(), protoItem.item_id(), protoItem.item_num(), protoItem.bind());
						g_GetItemMgr()->FreeItemObj(pItem);
					}
					else
					{
						if (ValidEquipPos((uint8_t)pItem->GetIndex()))
						{
							pItem->Identify(true);		//这里做一下容错处理  穿戴的装备肯定是鉴定状态
							m_vecPlayerEquip[pItem->GetIndex()] = (CEquip*)pItem;
						}
						else
						{
							LogErrFmtPrint("[logic] PackagePart::Init 66, ValidEquipPos false....index:%d, item_id:%u,num:%d,bind:%d..", protoItem.index(), protoItem.item_id(), protoItem.item_num(), protoItem.bind());
							g_GetItemMgr()->FreeItemObj(pItem);
						}
					}
				}
				else
				{
					MMOLOG_FMT_ERROR("[logic] PackagePart::Init  , nullptr == pItem...");
				}
			} // end of for (uint16_t k = 0; k < nequipSize; ++k)

			uint16_t nGodEquipSize = (uint16_t)protoEquip.god_equip_size();
			for (uint16_t k = 0; k < nGodEquipSize; ++k)
			{
				const ItemProtoInfo &protoItem = protoEquip.god_equip(k);
				CItemBase *pItem = g_GetItemMgr()->MakeItemObj(EItemType_equip);
				if (nullptr != pItem)
				{
					if (!pItem->SetItemProto(protoItem))
					{
						LogErrFmtPrint("[logic] PackagePart::Init 77, item SetItemProto failed....index:%d, item_id:%u,num:%d,bind:%d..", protoItem.index(), protoItem.item_id(), protoItem.item_num(), protoItem.bind());
						g_GetItemMgr()->FreeItemObj(pItem);
					}
					else
					{
						if (ValidEquipPos((uint8_t)pItem->GetIndex()))
						{
							pItem->Identify(true);		//这里做一下容错处理  穿戴的装备肯定是鉴定状态
							m_vecPlayerGodEquip[pItem->GetIndex()] = (CEquip*)pItem;
						}
						else
						{
							LogErrFmtPrint("[logic] PackagePart::Init 77, ValidEquipPos false....index:%d, item_id:%u,num:%d,bind:%d..", protoItem.index(), protoItem.item_id(), protoItem.item_num(), protoItem.bind());
							g_GetItemMgr()->FreeItemObj(pItem);
						}
					}
				}
				else
				{
					MMOLOG_FMT_ERROR("[logic] PackagePart::Init  , nullptr == pItem...");
				}
			} // end of for (uint16_t k = 0; k < nequipSize; ++k)

			uint16_t nslotSize = (uint16_t)protoEquip.equip_slot_size();
			for (uint16_t k = 0; k < nslotSize; ++k)
			{
				const EquipSlotProto &protoSlot = protoEquip.equip_slot(k);
				m_vecEquipSlot[protoSlot.index()].SetEquipSlot(protoSlot);
			}
			GetRuneItemId(m_equipFacade.runeDWId, m_equipFacade.runeYKId);

			uint16_t nfashionSize = (uint16_t)protoEquip.fashion_size();
			for (uint16_t i = 0; i < nfashionSize; ++i)
			{
				const FashionProtoInfo &fashionProto = protoEquip.fashion(i);
				CFashion fashion;
				fashion.fashionId = fashionProto.fashion_id();
				fashion.leftMin = fashionProto.left_time();
				fashion.isDress = fashionProto.is_dress();
				m_vecPlayerFashion.push_back(fashion);
				if (fashion.isDress)
					m_equipFacade.fashionId = fashion.fashionId;
			}
		}		
	}

	//检查物品CD
	CheckAllCd();
	//背包标签页信息
	LabelInfo();
	//更新角色外观
	UpdateFacade();
	//装备加载完成，计算装备属性
	CalcEquipAttr(false);

	g_GetTimerAxis()->SetTimer(ETimer_ID_Package_Fashion, 60 * 1000, this);
	g_GetTimerAxis()->SetTimer(ETimer_ID_Package_GodEquip, 1 * 1000, this);
	return true;
}

bool PackagePart::UnInit()
{
	Part::UnInit();
	//
	g_GetTimerAxis()->KillTimer(0, this);

	m_mapMsgfunc.clear();
	m_nExpandNum = 0;
	m_mapItemCd.clear();
	m_nLastSortTime = 0;
	memset(&m_nLabelOpenGrid[0], 0, sizeof(m_nLabelOpenGrid));

	VEC_PACKAGE_ITEM::iterator iter = m_vecItems.begin();
	for (; iter != m_vecItems.end(); ++iter)
	{
		CItemBase *pItem = (*iter);
		if (nullptr != pItem)
		{
			g_GetItemMgr()->FreeItemObj(pItem);
		}
	}
	m_vecItems.clear();
	m_vecPlayerFashion.clear();

	VEC_PLAYER_EQUIP::iterator iterEquip = m_vecPlayerEquip.begin();
	for (; iterEquip != m_vecPlayerEquip.end(); ++iterEquip)
	{
		CEquip *pEquip = (*iterEquip);
		if (nullptr != pEquip)
		{
			g_GetItemMgr()->FreeItemObj(pEquip);
		}
	}

	VEC_PLAYER_EQUIP::iterator iterGodEquip = m_vecPlayerGodEquip.begin();
	for (; iterGodEquip != m_vecPlayerGodEquip.end(); ++iterGodEquip)
	{
		CEquip *pGodEquip = (*iterGodEquip);
		if (nullptr != pGodEquip)
		{
			g_GetItemMgr()->FreeItemObj(pGodEquip);
		}
	}

	m_vecPlayerEquip.clear();
	m_vecPlayerGodEquip.clear();
	m_vecEquipSlot.clear();

	VEC_PACKAGE_ITEM::iterator iterStorage = m_vecStorage.begin();
	for (; iterStorage != m_vecStorage.end(); ++iterStorage)
	{
		CItemBase *pItem = (*iterStorage);
		if (nullptr != pItem)
		{
			g_GetItemMgr()->FreeItemObj(pItem);
		}
	}
	m_vecStorage.clear();
	m_storageExpand = 0;
	m_lastStorageSort = 0;

	std::deque<CItemBase*>::iterator iterBuyItem = m_dequeRebuyItem.begin();
	for (; iterBuyItem != m_dequeRebuyItem.end(); ++iterBuyItem)
	{
		CItemBase *pItem = (*iterBuyItem);
		if (nullptr != pItem)
		{
			g_GetItemMgr()->FreeItemObj(pItem);
		}
	}
	m_dequeRebuyItem.clear();

	return true;
}

bool PackagePart::OnMsgHandle(uint32_t cmd, const char* data, uint32_t len)
{
	mapMsgFunc::iterator iter = m_mapMsgfunc.find(cmd);
	if (iter == m_mapMsgfunc.end())
		LogErrFmtPrint("msg dont exit in PackagePart, cmd:%d", cmd);
	else
		(this->*m_mapMsgfunc[cmd])(data, len);

	return true;
}

bool PackagePart::SynOnLogin()
{
	
	//因为这个接口 只是登录才会调用，切换逻辑节点不会调用到这里，所以第一次登陆游戏可以放到这里判断
	Player *pPlayer = dynamic_cast<Player*>(m_pMaster);
	if (nullptr != pPlayer && pPlayer->GetLogoutTime() <= 0)
	{
		//第一次登陆游戏
		FirstLogin();
	}

	return true;
}

void PackagePart::OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen)
{

}

void PackagePart::OnTimer(uint32_t nTimerID)
{
	switch (nTimerID)
	{
	case ETimer_ID_Package_Fashion:
	{
		UpdateFashion();
	}
	break;
	case ETimer_ID_Package_GodEquip:
	{
		UpdateGodEquip();
	}
	break;
	default:
		break;
	}
}

bool PackagePart::SaveDB(CharacterDBInfo& characterDB)
{
	CharacterDBPackageData *protoDBPackage = characterDB.mutable_itemdata();
	if (nullptr != protoDBPackage)
	{
		protoDBPackage->set_expand_num(m_nExpandNum);


		uint16_t taskStartIdx = GetLabelStartIdx(EPackageLabel_task);
		uint16_t taskEndIdx = GetLabelEndIdx(EPackageLabel_task);
		for (uint16_t m = taskStartIdx; m <= taskEndIdx; ++m)
		{
			CItemBase *pItem = GetItemByIndex(m);
			if (nullptr != pItem)
			{
				ItemProtoInfo *protoItem = protoDBPackage->add_task();
				SetUpdateItemInfo(pItem, protoItem);
			}
		}

		uint16_t allStartIdx = GetLabelStartIdx(EPackageLabel_all);
		uint16_t allEndIdx = GetLabelEndIdx(EPackageLabel_all);
		for (uint16_t n = allStartIdx; n <= allEndIdx; ++n)
		{
			CItemBase *pItem = GetItemByIndex(n);
			if (nullptr != pItem)
			{
				ItemProtoInfo *protoItem = protoDBPackage->add_all();
				SetUpdateItemInfo(pItem, protoItem);
			}
		}

		//cd
		MAP_UINT32_UINT64::iterator iterCd = m_mapItemCd.begin();
		for (; iterCd != m_mapItemCd.end(); ++iterCd)
		{
			PackageCdDBProto *protoCd = protoDBPackage->add_cd();
			if (nullptr != protoCd)
			{
				protoCd->set_itemid_or_groupid(iterCd->first);
				protoCd->set_start_cd(iterCd->second);
			}
		}


		//storage
		CharacterDBStorageData *protoStorage = protoDBPackage->mutable_storage();
		if (nullptr != protoStorage)
		{
			protoStorage->set_expand_num(m_storageExpand);
			VEC_PACKAGE_ITEM::iterator iterStorage = m_vecStorage.begin();
			for (; iterStorage != m_vecStorage.end(); ++iterStorage)
			{
				CItemBase *pItem = (*iterStorage);
				if (nullptr != pItem)
				{
					ItemProtoInfo *protoItem = protoStorage->add_item_lst();
					SetUpdateItemInfo(pItem, protoItem);
				}
			}
		}

	}
	CharacterDBEquipData *protoDBEquip = characterDB.mutable_equipdata();
	if (nullptr != protoDBEquip)
	{
		protoDBEquip->set_equip_type(m_equipFacade.showType);
		for (uint8_t k = EEquipPos_none + 1; k < EEquipPos_limit; ++k)
		{
			EquipSlot &slot = m_vecEquipSlot[k];
			EquipSlotProto *protoSlot = protoDBEquip->add_equip_slot();
			SetEquipSlotInfo(slot, protoSlot);

			CEquip *pEquip = GetEquip(k);
			if (nullptr != pEquip)
			{
				ItemProtoInfo *protoItem = protoDBEquip->add_equip();
				SetUpdateItemInfo(pEquip, protoItem);
			}
			
			CEquip *pGodEquip = GetEquip(k, EEquipType_GodEquip);
			if (nullptr != pGodEquip)
			{
				ItemProtoInfo *protoItem = protoDBEquip->add_god_equip();
				SetUpdateItemInfo(pGodEquip, protoItem);
			}
		}

		for (VEC_PLAYER_FASHION::iterator it = m_vecPlayerFashion.begin(); it != m_vecPlayerFashion.end(); it++)
		{
			FashionProtoInfo *fashionProto = protoDBEquip->add_fashion();
			if (fashionProto)
			{
				fashionProto->set_fashion_id((*it).fashionId);
				fashionProto->set_left_time((*it).leftMin);
				fashionProto->set_is_dress((*it).isDress);
			}
		}
	}

	return true;
}

//获取指定物品数量
int32_t PackagePart::GetItemNum(uint32_t nItemID, int32_t &nUnBindNum, int32_t &nBindNum)
{
	return GetPackageItemNum(nItemID, nUnBindNum, nBindNum);
}
//是否存在物品
bool PackagePart::HasItem(LIST_ITEM &lstItem)
{
	ORDER_MAP_UINT16_INT32 mapGridReduceNum;
	if (!HasPackageItem(lstItem,mapGridReduceNum))
	{
		return false;
	}

	return true;
}

//移除物品
bool PackagePart::RemoveItem(uint32_t nItemID, int32_t nNum, SItemSourceParam &sourceParam, int8_t byBind /*= (int8_t)EBindState::EBindState_all*/)
{
	LIST_ITEM lstItem;
	lstItem.clear();
	SItem item;
	item.nItemID = nItemID;
	item.nNum = nNum;
	item.byBind = byBind;
	lstItem.push_back(item);
	return RemoveItem(lstItem, sourceParam);
}
//移除物品
bool PackagePart::RemoveItem(LIST_ITEM &lstItem, SItemSourceParam &sourceParam)
{

	ORDER_MAP_UINT16_INT32 mapGridReduceNum;
	mapGridReduceNum.clear();
	if (!HasPackageItem(lstItem, mapGridReduceNum))
	{
		return false;
	}
	//因为上面判断过，所以这里直接移除物品
	MAP_UINT32_INT32 mapItemNum;
	mapItemNum.clear();
	RemovePackageItem(mapGridReduceNum,mapItemNum);

	//
	OnRemoveItemEvent(mapItemNum, sourceParam);

	//物品流水日志
	ItemLog(TID_ITEM_DEL, mapItemNum, sourceParam.source);

	return true;
}

//移除物品 index,num nGetType : 物品移除来源（暂时没有）
bool PackagePart::RemoveItemByIndex(uint16_t nIndex, int32_t nNum, SItemSourceParam &sourceParam)
{
	MAP_UINT16_INT32 mapIndex;
	mapIndex.clear();
	mapIndex[nIndex] = nNum;
	return RemoveItem(mapIndex, sourceParam);
}
//移除物品 index-num
bool PackagePart::RemoveItem(MAP_UINT16_INT32 &mapIndexItem, SItemSourceParam &sourceParam)
{
	ORDER_MAP_UINT16_INT32 mapIdxReduceNum;
	mapIdxReduceNum.clear();
	if (!HasPackageItem(mapIndexItem, mapIdxReduceNum))
	{
		return false;
	}
	MAP_UINT32_INT32 mapItemNum;
	mapItemNum.clear();
	RemovePackageItem(mapIdxReduceNum, mapItemNum);
	//
	OnRemoveItemEvent(mapItemNum, sourceParam);

	//物品流水日志
	ItemLog(TID_ITEM_DEL, mapItemNum, sourceParam.source);
	return true;
}
//移除穿戴装备 index
bool PackagePart::RemovePlayerEquip(SET_UINT8 &setIdx)
{
	//先校验装备
	VEC_PLAYER_EQUIP vecDelEquip;
	vecDelEquip.clear();
	SET_UINT8::iterator iter = setIdx.begin();
	for (; iter != setIdx.end(); ++iter)
	{
		uint8_t pos = (*iter);
		if (!ValidEquipPos(pos))
		{
			return false;
		}
		CEquip *pEquip = GetEquip(pos);
		if (nullptr == pEquip)
		{
			return false;
		}
		vecDelEquip.push_back(pEquip);
	}
	//
	PlayerEquipDelNotify notify;
	VEC_PLAYER_EQUIP::iterator iterEquip = vecDelEquip.begin();
	for (; iterEquip != vecDelEquip.end(); ++iterEquip)
	{
		CEquip *pEquip = (*iterEquip);
		if (nullptr == pEquip)
		{
			continue;
		}
		uint8_t pos = pEquip->GetIndex();
		//设置装备位置为空
		SetEquipByIndex(pos, nullptr);
		//回收装备对象
		g_GetItemMgr()->FreeItemObj(pEquip);
		//
		notify.add_pos(pos);
	}

	if (notify.pos_size() > 0)
	{
		CalcEquipAttr(true);
		m_pMaster->SendDataToClientEx(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLYAER_EQUIP_DEL, &notify);

		uint32_t new_clothId = 0;
		uint32_t new_weaponId = 0;
		uint32_t new_wingId = 0;
		GetFacade(new_clothId, new_weaponId, new_wingId);
		if (new_clothId != m_equipFacade.clothesId || new_weaponId != m_equipFacade.weaponId || new_wingId != m_equipFacade.wingId)
		{
			m_equipFacade.clothesId = new_clothId;
			m_equipFacade.weaponId = new_weaponId;
			m_equipFacade.wingId = new_wingId;
			FacadeChange(true);
		}
	}

	return true;
}

//是否能添加物品
bool PackagePart::CanAddItem(LIST_ITEM &lstItem)
{
	VEC_ITEM_PROTO_EX vecInProtoEx;
	MAP_LABEL_LIST_ITEM_EX mapOutLabelItemEx;
	MAP_LABEL_VEC_ITEM_PROTO_EX mapOutLabelVecPorotEx;
	MergePackageItemList(lstItem, vecInProtoEx, mapOutLabelItemEx, mapOutLabelVecPorotEx);

	MAP_UINT16_INT32 mapOutGridResultNum;
	MAP_INDEX_ITEM_PROTO_EX mapOutNewIdxItemProtoEx;
	return CanPackageAddItem(mapOutLabelItemEx, mapOutLabelVecPorotEx, mapOutGridResultNum, mapOutNewIdxItemProtoEx);
}
//能否添加物品
bool PackagePart::CanAddItem(VEC_ITEM_PROTO_EX &vecProtoItemsEx)
{
	LIST_ITEM lstItem;
	lstItem.clear();
	MAP_LABEL_LIST_ITEM_EX mapOutLabelItem;
	MAP_LABEL_VEC_ITEM_PROTO_EX mapLabelVecProtoEx;
	MergePackageItemList(lstItem, vecProtoItemsEx, mapOutLabelItem, mapLabelVecProtoEx);

	MAP_UINT16_INT32 mapGridAddNum;
	MAP_INDEX_ITEM_PROTO_EX mapIndexProtoEx;
	return CanPackageAddItem(mapOutLabelItem, mapLabelVecProtoEx, mapGridAddNum, mapIndexProtoEx);
}
//添加物品
bool PackagePart::AddItem(uint32_t nItemID, int32_t nNum, SItemSourceParam &sourceParam, int8_t byBind /*= (int8_t)EBindState::EBindState_no*/)
{
	LIST_ITEM lstItem;
	lstItem.clear();
	SItem item;
	item.nItemID = nItemID;
	item.nNum = nNum;
	item.byBind = byBind;
	lstItem.push_back(item);
	return AddItem(lstItem, sourceParam);
}
//添加物品 nGetType : 物品来源（暂时没有）
bool PackagePart::AddItem(LIST_ITEM &lstItem, SItemSourceParam &sourceParam, bool update /*= true*/)
{
	VEC_ITEM_PROTO_EX vecInProtoEx;
	MAP_LABEL_LIST_ITEM_EX mapOutLabelItemEx;
	MAP_LABEL_VEC_ITEM_PROTO_EX mapOutLabelVecPorotEx;
	MergePackageItemList(lstItem, vecInProtoEx, mapOutLabelItemEx, mapOutLabelVecPorotEx);

	MAP_UINT16_INT32 mapOutGridAddNum;
	MAP_INDEX_ITEM_PROTO_EX mapOutNewIdxItemProtoEx;
	if (!CanPackageAddItem(mapOutLabelItemEx, mapOutLabelVecPorotEx, mapOutGridAddNum, mapOutNewIdxItemProtoEx))
	{
		return false;
	}
	//先清空索引记录
	ClearIdxRecord();
	//已经判断过了，这里直接添加物品
	AddPackageItem(mapOutGridAddNum, mapOutNewIdxItemProtoEx, update);
	//增加物品，触发事件
	OnAddItemEvent(mapOutGridAddNum, mapOutNewIdxItemProtoEx, sourceParam);
	//物品流水日志
	ItemLog(TID_ITEM_GET, mapOutGridAddNum, sourceParam.source);
	return true;
}

//添加物品
bool PackagePart::AddItem(VEC_ITEM_PROTO &vecProtoItems, SItemSourceParam &sourceParam, bool update/* = true*/)
{
	VEC_ITEM_PROTO_EX vecProtoEx;
	vecProtoEx.clear();
	VEC_ITEM_PROTO::iterator iter = vecProtoItems.begin();
	for (; iter != vecProtoItems.end(); ++iter)
	{
		ItemProtoInfo *proto = (*iter);
		if (nullptr != proto)
		{
			ItemProtoInfo protoEx(*proto);
			vecProtoEx.push_back(protoEx);
		}
	}
	return AddItem(vecProtoEx, sourceParam, update);
}
//添加物品 nGetType : 物品来源（暂时没有）
bool PackagePart::AddItem(VEC_ITEM_PROTO_EX &vecProtoItemsEx, SItemSourceParam &sourceParam, bool update/* = true*/)
{
	LIST_ITEM lstItem;
	lstItem.clear();
	MAP_LABEL_LIST_ITEM_EX mapOutLabelItem;
	MAP_LABEL_VEC_ITEM_PROTO_EX mapLabelVecProtoEx;
	MergePackageItemList(lstItem, vecProtoItemsEx, mapOutLabelItem, mapLabelVecProtoEx);

	MAP_UINT16_INT32 mapGridAddNum;
	MAP_INDEX_ITEM_PROTO_EX mapIndexProtoEx;
	if (!CanPackageAddItem(mapOutLabelItem, mapLabelVecProtoEx, mapGridAddNum, mapIndexProtoEx))
	{
		return false;
	}
	//清空
	ClearIdxRecord();
	//前面已经判断过，直接增加
	AddPackageItem(mapGridAddNum, mapIndexProtoEx, update);
	//增加物品，触发事件
	OnAddItemEvent(mapGridAddNum, mapIndexProtoEx, sourceParam);
	//物品流水日志
	ItemLog(TID_ITEM_GET, mapGridAddNum, sourceParam.source);
	return true;
}

bool PackagePart::AddItem(VEC_ITEM_PROTO_EX &vecProtoItemsEx, VEC_ITEM_PROTO_EX &vecProtoItemsOut, SItemSourceParam &sourceParam, bool update/* = true*/)
{
	LIST_ITEM lstItem;
	lstItem.clear();
	MAP_LABEL_LIST_ITEM_EX mapOutLabelItem;
	MAP_LABEL_VEC_ITEM_PROTO_EX mapLabelVecProtoEx;
	MergePackageItemList(lstItem, vecProtoItemsEx, mapOutLabelItem, mapLabelVecProtoEx);

	MAP_UINT16_INT32 mapGridAddNum;
	MAP_INDEX_ITEM_PROTO_EX mapIndexProtoEx;
	if (!CanPackageAddItem(mapOutLabelItem, mapLabelVecProtoEx, mapGridAddNum, mapIndexProtoEx))
	{
		return false;
	}
	//清空
	ClearIdxRecord();
	//前面已经判断过，直接增加
	AddPackageItem(mapGridAddNum, mapIndexProtoEx, update);
	//增加物品，触发事件
	OnAddItemEvent(mapGridAddNum, mapIndexProtoEx, sourceParam);
	//填充传出参数
	OnAddItemParam(mapGridAddNum, mapIndexProtoEx,vecProtoItemsOut);
	//物品流水日志
	ItemLog(TID_ITEM_GET, mapGridAddNum, sourceParam.source);
	return true;
}
//清空背包所有物品
bool PackagePart::ClearPackage()
{
	int8_t byPackageType = EPackageType_packge;
	uint16_t nStartIndex = GetLabelStartIdxByPackageType(EPackageLabel_all, byPackageType);
	uint16_t nEndIndex = GetLabelEndIdxByPackageType(EPackageLabel_all, byPackageType);
	if (!ValidIndexByPackageType(nStartIndex, EPackageType_packge) || !ValidIndexByPackageType(nEndIndex, byPackageType))
	{
		MMOLOG_FMT_ERROR("[logic] PackagePart::ClearPackage ValidIndexByPackageType false, nStartIndex[%d] nEndIndex[%d], byPackageType:%d ", nStartIndex, nEndIndex, byPackageType);
		return false;
	}
	//
	ORDER_MAP_UINT16_INT32 mapGridReduceNum;
	mapGridReduceNum.clear();
	for (size_t i = nStartIndex; i <= nEndIndex; ++i)
	{
		CItemBase *pItem = GetItemByPackageType(byPackageType, i);
		if (nullptr != pItem)
		{
			mapGridReduceNum[i] = pItem->GetNum();
		}
	}
	//移除物品
	MAP_UINT32_INT32 mapItemNum;
	return RemoveBagItem(mapGridReduceNum, mapItemNum,byPackageType);
}
//扩展背包
int32_t PackagePart::Expand(uint16_t nNum)
{
	if (m_nOpenGrid >= PACKAGE_MAX_GRID_NUM)
	{
		return RET_PACKAGE_EXPAND_LIMIT;
	}
	uint16_t nLefNum = PACKAGE_MAX_GRID_NUM - m_nOpenGrid;
	uint16_t nExpand = nNum * PACKAGE_EXPAND_GRID_NUM;
	if (nExpand >= nLefNum)
	{
		nExpand = nLefNum;
	}
	//
	m_nExpandNum += nExpand;
	m_nOpenGrid += nExpand;

	UpdatePackageExpand();

	return RET_SUCCESS;
}

//扩展仓库
int32_t PackagePart::ExpandStorage(uint16_t nNum)
{
	StorageExpandRsp rsp;
	int16_t leftNum = STORAGE_MAX_GRID_NUM - STORAGE_INIT_GRID_NUM - m_storageExpand;
	if (leftNum <= 0)
	{
		return RET_PACKAGE_STORAGE_EXPAND_LIMIT;
	}
	int16_t expandNum = nNum * STORAGE_EXPAND_GRID_NUM;	
	if (expandNum >= leftNum)
	{
		expandNum = leftNum;
	}	
	m_storageExpand += expandNum;

	UpdateStorageExpand();

	return RET_SUCCESS;
}

//获取装备信息
VEC_PLAYER_EQUIP *PackagePart::GetPlayerEquip()
{
	return &m_vecPlayerEquip;
}

//获取索引位置物品
const CItemBase *PackagePart::GetItem(uint16_t nIndex)
{
	return GetItemByIndex(nIndex);
}
//获取物品（根据tem.xlsx 表中 subType 字段 获取物品）
const CItemBase *PackagePart::GetItemByType(int32_t itemSubType)
{
	VEC_PACKAGE_ITEM::iterator iter = m_vecItems.begin();
	for (; iter != m_vecItems.end(); ++iter)
	{
		CItemBase *pItemBase = (*iter);
		if (nullptr != pItemBase)
		{
			const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItemBase->GetItemID());
			if (nullptr != pItemCfg && itemSubType == pItemCfg->subType)
			{
				return pItemBase;
			}
		}
	}
	return nullptr;
}

//移除所有指定类型的物品（根据 tem.xlsx 表中 subType 字段 移除物品）
bool PackagePart::RemoveAllByType(int32_t itemSubType, SItemSourceParam &sourceParam)
{
	MAP_UINT16_INT32 mapIdxNum;
	mapIdxNum.clear();
	VEC_PACKAGE_ITEM::iterator iter = m_vecItems.begin();
	for (; iter != m_vecItems.end(); ++iter)
	{
		CItemBase *pItemBase = (*iter);
		if (nullptr != pItemBase)
		{
			const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItemBase->GetItemID());
			if (nullptr != pItemCfg && itemSubType == pItemCfg->subType)
			{
				mapIdxNum[pItemBase->GetIndex()] = pItemBase->GetNum();
			}
		}
	}
	if (mapIdxNum.size() > 0)
	{
		RemoveItem(mapIdxNum, sourceParam);
		return true;
	}
	return false;
}

//获取所有可掉落的穿戴装备
void PackagePart::GetAllCanDropEquip(VEC_COMMON_ITEM &vecEquip)
{
	VEC_PLAYER_EQUIP::iterator iter = m_vecPlayerEquip.begin();
	for (; iter != m_vecPlayerEquip.end(); ++iter)
	{
		CEquip *pEquip = (*iter);
		if (nullptr == pEquip)
		{
			continue;
		}
		if (!g_GetItemMgr()->CanDieDrop(pEquip->GetItemID(), pEquip->GetBind()))
		{
			continue;
		}
		vecEquip.push_back((const CItemBase*)pEquip);
	}
}
//获取所有可掉落的背包物品
void PackagePart::GetAllCanDropPackage(VEC_COMMON_ITEM &vecPakcage)
{
	VEC_PACKAGE_ITEM::iterator iter = m_vecItems.begin();
	for (; iter != m_vecItems.end(); ++iter)
	{
		const CItemBase *pItem = (*iter);
		if (nullptr == pItem)
		{
			continue;
		}
		if (!g_GetItemMgr()->CanDieDrop(pItem->GetItemID(),pItem->GetBind()))
		{
			continue;
		}
		vecPakcage.push_back((const CItemBase*)pItem);
	}
}

//获取外观
void PackagePart::GetFacade(uint32_t &clothesId, uint32_t &weaponId, uint32_t &wingId)
{
	clothesId = 0;
	weaponId = 0;
	wingId = 0;
	CEquip *pClothes = GetEquip(EEquipPos_clothes);
	CEquip *pWeapon = GetEquip(EEquipPos_weapon);
	CEquip *pWing = GetEquip(EEquipPos_wing);
	if (nullptr != pClothes)
	{
		clothesId = pClothes->GetItemID();
	}
	if (nullptr != pWeapon)
	{
		weaponId = pWeapon->GetItemID();
	}
	if (nullptr != pWing)
	{
		wingId = pWing->GetItemID();
	}
}

//激活
int32_t PackagePart::Active(uint16_t nIdx)
{
	CItemBase *pItem = GetItemByIndex(nIdx);
	if (nullptr == pItem)
		return RET_FAIL;
	
	if (pItem->ActiveStatus())
		return RET_TREASURE_ALREADY_ACTIVE;

	PackageUpdateRet update;
	uint16_t begIdx = GetLabelStartIdx(EPackageLabel_all);
	uint16_t endIdx = GetLabelEndIdx(EPackageLabel_all);
	for (uint16_t i = begIdx; i <= endIdx; ++i)
	{
		if (i == nIdx) //上面已经判断过，这里不再判断
			continue;

		CItemBase *pCheckItem = GetItemByIndex(i);
		if (nullptr == pCheckItem)
			continue;

		if (!pCheckItem->ActiveStatus())
			continue;

		//已经有其他物品激活了
		pCheckItem->ActiveStatus(0);
		ItemProtoInfo *checkProto = update.add_item_list();
		if (nullptr == checkProto)
			continue;

		SetUpdateItemInfo(pCheckItem, checkProto);
	}

	pItem->ActiveStatus(1);
	ItemProtoInfo *proto = update.add_item_list();
	if (nullptr != proto)
	{
		SetUpdateItemInfo(pItem, proto);
	}
	

	UpdatePackageInfo(update);
	return RET_SUCCESS;
}

void PackagePart::UnActive()
{
	PackageUpdateRet update;
	uint16_t begIdx = GetLabelStartIdx(EPackageLabel_all);
	uint16_t endIdx = GetLabelEndIdx(EPackageLabel_all);
	for (uint16_t i = begIdx; i <= endIdx; ++i)
	{
		CItemBase *pItem = GetItemByIndex(i);
		if (nullptr == pItem)
			continue;

		if (!pItem->ActiveStatus())
			continue;

		ItemProtoInfo *checkProto = update.add_item_list();
		if (nullptr == checkProto)
			continue;

		pItem->ActiveStatus(0);
		SetUpdateItemInfo(pItem, checkProto);
	}

	if (update.item_list_size() > 0)
	{
		UpdatePackageInfo(update);
	}
}

//设置跑商资金
bool PackagePart::SetRunBusiness(uint16_t nIndex, int32_t fund)
{
	CItemBase *pItemBase = GetItemByIndex(nIndex);
	if (nullptr != pItemBase)
	{
		pItemBase->SetFund(fund);
		//
		PackageUpdateRet update;
		ItemProtoInfo *proto = update.add_item_list();
		if (nullptr != proto)
		{
			SetUpdateItemInfo(pItemBase, proto);
		}
		UpdatePackageInfo(update);

		return true;
	}
	return false;
}

//设置跑商均价
void PackagePart::SetRunAvePrice(int32_t count, int32_t money)
{
	if (m_setIdxRecord.size() <= 0 )
		return;

	uint16_t nIndex = *(m_setIdxRecord.begin());
	CItemBase* pItemBase = GetItemByIndex(nIndex);
	if (nullptr == pItemBase)
		return;

	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItemBase->GetItemID());
	if (nullptr == pItemCfg || (int32_t)EItemSubType::EItemSubType_run_business_trade != pItemCfg->subType)
		return;

	int32_t nowNum = pItemBase->GetNum();
	int32_t prePrice = pItemBase->GetAvePrice();
	int32_t preCount = nowNum >= count ? nowNum - count : 0;
	int32_t preTotalValue = prePrice * preCount;
	int32_t nowTotalValue = money + preTotalValue;
	int32_t nowPrice = nowTotalValue / (float)nowNum;
	pItemBase->SetAvePrice(nowPrice);

	PackageUpdateRet update;
	ItemProtoInfo *proto = update.add_item_list();
	if (nullptr != proto)
	{
		SetUpdateItemInfo(pItemBase, proto);
		UpdatePackageInfo(update);
	}
}

//添加打造的物品
bool PackagePart::AddItemByMake(uint32_t nItemID, const char *szMaker, SItemCond &itemCond, SItemSourceParam &sourceParam, int8_t byBind /*= (int8_t)EBindState::EBindState_no*/)
{
	int8_t byType = EItemType_common;
	uint8_t byLabel = EPackageLabel_none;
	byLabel = byLabel;//消除警告
	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(nItemID);
	if (nullptr == pItemCfg)
	{
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(nItemID);
		if (nullptr == pEquipCfg)
		{
			return false;
		}
		byType = EItemType_equip;
		byLabel = g_GetItemMgr()->GetPackageLabel(pEquipCfg);
	}
	else
	{
		byLabel = g_GetItemMgr()->GetPackageLabel(pItemCfg);
	}
	CItemBase *pItem = g_GetItemMgr()->MakeItemObj(byType);
	if (nullptr == pItem)
	{
		return false;
	}
	if (!pItem->Init(0, nItemID, itemCond, 1, byBind))
	{
		g_GetItemMgr()->FreeItemObj(pItem);
		return false;
	}
	pItem->SetMaker(szMaker);
	pItem->Identify(false);		//设置打造装备为未鉴定状态

	ItemProtoInfo proto;
	if (!SetUpdateItemInfo(pItem, &proto))
	{
		g_GetItemMgr()->FreeItemObj(pItem);
		return false;
	}
	VEC_ITEM_PROTO_EX vecItemEx;
	vecItemEx.clear();
	vecItemEx.push_back(proto);
	return AddItem(vecItemEx, sourceParam);
}

//使用物品 nIndex:物品所在背包索引
int32_t PackagePart::UseItem(uint16_t nIndex, int32_t nNum, UseItemArgProto &protoArg)
{
	CItemBase *pItem = GetItemByIndex(nIndex);
	if (nullptr == pItem)
	{
		return RET_PACKAGE_ITEM_NOT_EXITS;
	}
	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItem->GetItemID());
	if (nullptr == pItemCfg)
	{
		//物品不存在
		return RET_PACKAGE_ITEM_NOT_EXITS;
	}
	int32_t ret = UseItem(pItem, nNum, protoArg);
	if (RET_SUCCESS != ret)
	{
		return ret;
	}
	//
	SItemSourceParam sourceParam;
	sourceParam.source = S_USE_ITEM;
	if (pItemCfg->isUsedDestroy)
	{
		//移除物品					
		RemoveItemByIndex(pItem->GetIndex(), nNum, sourceParam);
	}
	else if ((int32_t)EItemFuncType::EItemFuncType_HpMpBox == pItemCfg->functionType)
	{
		if (pItem->GetHpMpValue() <= 0)//血包类物品需要检查下 HP,MP可用的值是否用完了  
		{
			RemoveItemByIndex(pItem->GetIndex(), nNum, sourceParam);
		}
		else
		{
			//学包剩余可使用的HP MP变化需要通知前端
			PackageUpdateRet protoRet;
			AddPackageUpdateInfo(pItem, protoRet);
			UpdatePackageInfo(protoRet);
		}
	}
	return RET_SUCCESS;
}
//使用物品 pItem:物品指针，只是使用，不负责回收物品指针
int32_t PackagePart::UseItem(CItemBase *pItem, int32_t nNum, UseItemArgProto protoArg)
{
	int32_t nRetCode = RET_FAIL;
	if (nullptr == pItem)
	{
		return RET_FAIL;
	}
	else if ((int32_t)pItem->GetNum() < nNum)
	{
		//数量不够 RET_PACKAGE_ITEM_NUM_LACK
		return RET_PACKAGE_ITEM_NUM_LACK;
	}
	else
	{
		const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItem->GetItemID());
		if (nullptr == pItemCfg)
		{
			//物品不存在
			return RET_PACKAGE_ITEM_NOT_EXITS;
		}
		else if ((int32_t)ECdType::ECdType_independent == pItemCfg->coolingType
			&& IsInCd(pItemCfg->id)
			)
		{
			//cd中
			return RET_PACKAGE_ITEM_IN_CD;
		}
		else if ((int32_t)ECdType::ECdType_common == pItemCfg->coolingType
			&& IsInCd(pItemCfg->coolingGroup)
			)
		{
			//cd中
			return RET_PACKAGE_ITEM_IN_CD;
		}
		else
		{
			//具体物品的使用逻辑，后面添加
			nRetCode = g_GetItemUseMgr()->UseItem(pItem/*->GetItemID()*/, nNum, m_pMaster, protoArg);
			if (RET_SUCCESS == nRetCode)
			{
				//更新cd
				if ((int32_t)ECdType::ECdType_independent == pItemCfg->coolingType)
				{
					UpdateCd(pItemCfg->id);
				}
				else if ((int32_t)ECdType::ECdType_common == pItemCfg->coolingType)
				{
					UpdateCd(pItemCfg->coolingGroup);
				}

				//使用物品事件
				ItemUseEvent useEvent;
				useEvent.itemId = pItemCfg->id;
				useEvent.num = nNum;
				g_GetEvent()->FireExecute(EVENT_ITEM_USE, m_pMaster->GetCid(), CREATURE_PLAYER, &useEvent, sizeof(ItemUseEvent));
			}
		}
	}

	return nRetCode;
}


///////////////////////////////////  内部接口 ///////////////////////////////////////
//是否是有效的标签页
bool PackagePart::ValidLabel(uint8_t byLabel)
{
	if (EPackageLabel_task == byLabel || EPackageLabel_all == byLabel)
	{
		return true;
	}
	return false;
}
//通过格子索引获取标签
uint8_t PackagePart::GetLabelByIndex(uint16_t nIndex)
{
	if (!ValidIndex(nIndex))
	{
		return EItemLabel_none;
	}
	if (nIndex >= GetLabelStartIdx(EPackageLabel_all)
		&& nIndex <= GetLabelEndIdx(EPackageLabel_all)
		)
	{
		return EPackageLabel_all;
	}
	else if (
		nIndex >= GetLabelStartIdx(EPackageLabel_task)
		&& nIndex <= GetLabelEndIdx(EPackageLabel_task)
		)
	{
		return EPackageLabel_task;
	}
	return EPackageLabel_none;
}
//是否是有效的索引
bool PackagePart::ValidIndex(uint16_t nIndex)
{
	/*
	背包标签页索引 1- 200
	任务标签页  1002-1202
	*/
	if ((nIndex >= GetLabelStartIdx(EPackageLabel_all) && nIndex <= GetLabelEndIdx(EPackageLabel_all))
		|| (nIndex >= GetLabelStartIdx(EPackageLabel_task) && nIndex <= GetLabelEndIdx(EPackageLabel_task))
		)
	{
		return true;
	}
	return false;
}
//是否是有效的标签页索引
bool PackagePart::ValidLabelIndex(uint8_t byLabel, uint16_t nIndex)
{
	if (!ValidLabel(byLabel))
	{
		return false;
	}
	uint16_t nStartIdx = GetLabelStartIdx(byLabel);
	uint16_t nEndIdx = GetLabelEndIdx(byLabel);
	if (nIndex >= nStartIdx && nIndex <= nEndIdx)
	{
		return true;
	}
	return false;
}
//通过包裹类型判断是否是有效的索引
bool PackagePart::ValidIndexByPackageType(uint16_t nIndex, int8_t byPackageType)
{
	if (!ValidPackageType(byPackageType))
	{
		return false;
	}
	if (EPackageType_packge == byPackageType)
	{
		return ValidIndex(nIndex);
	}
	return ValidStorageIndex(nIndex);
}
//通过包裹类型判断是否是有效的标签页索引
bool PackagePart::ValidLabelIndexByPackageType(uint8_t byLabel, uint16_t nIndex, int8_t byPackageType)
{
	if (!ValidPackageType(byPackageType))
	{
		return false;
	}
	if (EPackageType_packge == byPackageType)
	{
		return ValidLabelIndex(byLabel, nIndex);
	}
	//仓库没有分标签页，所以这里只需要判断索引即可
	return ValidStorageIndex(nIndex);
}
//是否是有效的包裹类型
bool PackagePart::ValidPackageType(int8_t byPackageType)
{
	if (byPackageType > EPackageType_none && byPackageType < EPackageType_limit)
	{
		return true;
	}
	return false;
}
//设置物品
uint16_t PackagePart::SetItemByIndex(uint16_t nIndex, CItemBase *pItem)
{
	if (!ValidIndex(nIndex))
	{
		return 0;
	}
	m_vecItems[nIndex] = pItem;
	return nIndex;
}
//通过索引获取物品
CItemBase *PackagePart::GetItemByIndex(int16_t nIndex)
{
	if (ValidIndex(nIndex))
	{
		return m_vecItems[nIndex];
	}
	return nullptr;
}
//通过包裹类型获取物品 byPackageType:包裹类型 详见 EPackageType枚举
CItemBase *PackagePart::GetItemByPackageType(int8_t byPackageType, uint16_t nIndex)
{
	if (!ValidPackageType(byPackageType))
	{
		return nullptr;
	}
	if (EPackageType_packge == byPackageType)
	{
		return GetItemByIndex(nIndex);
	}
	else
	{
		return GetStorageItemByIndex(nIndex);
	}
}
// 通过包裹类型设置物品 :包裹类型 详见 EPackageType枚举
uint16_t PackagePart::SetItemByPackageType(int8_t byPackageType, uint16_t nIndex , CItemBase *pItem)
{
	if (!ValidPackageType(byPackageType))
	{
		return 0;
	}
	if (EPackageType_packge == byPackageType)
	{
		return SetItemByIndex(nIndex, pItem);
	}
	else
	{
		return SetStorageItemByIndex(nIndex, pItem);
	}
}
//获取标签页开启的格子数
uint16_t PackagePart::GetLabelOpenGrid(uint8_t byLabel)
{
	if (!ValidLabel(byLabel))
	{
		return 0;
	}
	return m_nLabelOpenGrid[byLabel];
}
//获取背包开启的格子数
uint16_t PackagePart::GetOpenGrid()
{
	return m_nOpenGrid;
}
//获取标签页起始索引
uint16_t PackagePart::GetLabelStartIdx(uint8_t byLabel)
{
	if (!ValidLabel(byLabel))
	{
		return 0;
	}
	if (EPackageLabel_all == byLabel) //全部背包起始索引为1
	{
		return 1;
	}
	return s_packageTaskStartIdx;
}
//获取标签页结束索引
uint16_t PackagePart::GetLabelEndIdx(uint8_t byLabel)
{
	if (!ValidLabel(byLabel))
	{
		return 0;
	}
	if (EPackageLabel_all == byLabel)
	{
		return GetLabelStartIdx(byLabel) + GetOpenGrid() - 1;
	}
	return s_packageTaskEndIdx;
}
//通过包裹类型获取格子起始索引
uint16_t PackagePart::GetLabelStartIdxByPackageType(uint8_t byLabel, int8_t byPackageType)
{
	if (!ValidPackageType(byPackageType))
	{
		return 0;
	}
	if (EPackageType_packge == byPackageType) //背包才分标签页，仓库不分标签页
	{
		if (!ValidLabel(byLabel))
		{
			return 0;
		}

		return GetLabelStartIdx(byLabel);
	}
	return GetStorageStartIdx();
}
//通过包裹类型获取格子结束索引
uint16_t PackagePart::GetLabelEndIdxByPackageType(uint8_t byLabel, int8_t byPackageType)
{
	if (!ValidPackageType(byPackageType))
	{
		return 0;
	}
	if (EPackageType_packge == byPackageType) //背包才分标签页，仓库不分标签页
	{
		if (!ValidLabel(byLabel))
		{
			return 0;
		}

		return GetLabelEndIdx(byLabel);
	}
	return GetStorageEndIdx();
}
//获取指定物品绑定和非绑定数量
int32_t PackagePart::GetPackageItemNum(uint32_t nItemID, int32_t &nUnBindNum, int32_t &nBindNum)
{
	ORDER_MAP_UINT16_INT32 mapUnbindGridHas;
	ORDER_MAP_UINT16_INT32 mapBindGridHas;
	return GetPackageItemNum(nItemID, nUnBindNum, nBindNum, mapUnbindGridHas, mapBindGridHas);
}

//获取背包指定物品绑定和非绑定数量
int32_t PackagePart::GetPackageItemNum(uint32_t nItemID, int32_t &nUnBindNum, int32_t &nBindNum, ORDER_MAP_UINT16_INT32 &mapUnbindGridHas, ORDER_MAP_UINT16_INT32 &mapBindGridHas)
{
	return GetBagItemNum(nItemID, nUnBindNum, nBindNum, mapUnbindGridHas, mapBindGridHas,EPackageType_packge);
}
//获取仓库指定物品的绑定和非绑定数量
int32_t PackagePart::GetStorageItemNum(uint32_t nItemID, int32_t &nUnBindNum, int32_t &nBindNum, ORDER_MAP_UINT16_INT32 &mapUnbindGridHas, ORDER_MAP_UINT16_INT32 &mapBindGridHas)
{
	return GetBagItemNum(nItemID, nUnBindNum, nBindNum, mapUnbindGridHas, mapBindGridHas, EPackageType_storage);
}
//获取指定物品绑定和非绑定数量
int32_t PackagePart::GetBagItemNum(uint32_t nItemID, int32_t &nUnBindNum, int32_t &nBindNum,ORDER_MAP_UINT16_INT32 &mapUnbindGridHas, ORDER_MAP_UINT16_INT32 &mapBindGridHas, int8_t byPackageType)
{
	VEC_PACKAGE_ITEM vecBindItem;
	VEC_PACKAGE_ITEM vecUnBindItem;
	uint8_t byLabel = EPackageLabel_none;
	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(nItemID);
	if (nullptr == pItemCfg)
	{
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(nItemID);
		if (nullptr == pEquipCfg)
		{
			LogErrFmtPrint("[logic] GetPackageItemNum...can not find item cfg ...nItemID[%u] ", nItemID);
			return 0;
		}
		byLabel = g_GetItemMgr()->GetPackageLabel(pEquipCfg);
	}
	else
	{
		byLabel = g_GetItemMgr()->GetPackageLabel(pItemCfg);
	}

	return GetLabelBagItemNum(byLabel, nItemID, nUnBindNum, nBindNum, vecUnBindItem, vecBindItem, mapUnbindGridHas, mapBindGridHas, byPackageType);
}


//获取指定物品绑定和非绑定数量
int32_t PackagePart::GetLabelBagItemNum(int8_t byLabel, uint32_t nItemID, int32_t &nUnBindNum, int32_t &nBindNum, VEC_PACKAGE_ITEM &vecUnBindItem, VEC_PACKAGE_ITEM &vecBindItem, ORDER_MAP_UINT16_INT32 &mapUnbindGridHas, ORDER_MAP_UINT16_INT32 &mapBindGridHas, int8_t byPackageType)
{
	nUnBindNum = 0;
	nBindNum = 0;
	mapUnbindGridHas.clear();
	mapBindGridHas.clear();
	if (!ValidLabel(byLabel) || !ValidPackageType(byPackageType))
	{
		return 0;
	}

	uint16_t nStartIndex = GetLabelStartIdxByPackageType(byLabel,byPackageType);
	uint16_t nEndIndex = GetLabelEndIdxByPackageType(byLabel,byPackageType);
	if (!ValidIndexByPackageType(nStartIndex,byPackageType) || !ValidIndexByPackageType(nEndIndex,byPackageType))
	{
		MMOLOG_FMT_ERROR("[logic] ValidIndexByPackageType false, nStartIndex[%d] nEndIndex[%d], byPackageType:%d ", nStartIndex, nEndIndex,byPackageType);
		return 0;
	}	
	
	//
	for (size_t i = nStartIndex; i <= nEndIndex; ++i)
	{
		CItemBase *pItem = GetItemByPackageType(byPackageType,i);
		if (nullptr != pItem && nItemID == pItem->GetItemID())
		{
			int8_t byBind = pItem->GetBind();
			if ((uint8_t)EBindState::EBindState_no == byBind)
			{
				nUnBindNum += pItem->GetNum();
				mapUnbindGridHas[pItem->GetIndex()] = pItem->GetNum();
				vecUnBindItem.push_back(pItem);
			}
			else if ((uint8_t)EBindState::EBindState_bind == byBind)
			{
				nBindNum += pItem->GetNum();
				mapBindGridHas[pItem->GetIndex()] = pItem->GetNum();
				vecBindItem.push_back(pItem);
			}
		}
	}
	return (nUnBindNum + nBindNum);
}

//是否存在物品
bool PackagePart::HasBagItem(const MAP_UINT16_INT32 &mapIdxNum, ORDER_MAP_UINT16_INT32 &mapGridReduceNum, int8_t byPackageType)
{
	if (!ValidPackageType(byPackageType))
	{
		return false;
	}
	mapGridReduceNum.clear();

	MAP_UINT16_INT32::const_iterator iter = mapIdxNum.begin();
	for (; iter != mapIdxNum.end(); ++iter)
	{
		uint16_t nIndex = iter->first;
		int32_t nNum = iter->second;
		if (nNum <= 0)
		{
			continue;
		}
		CItemBase *pItem = GetItemByPackageType(byPackageType,nIndex);
		if (nullptr == pItem || pItem->GetNum() < (uint32_t)nNum)
		{
			mapGridReduceNum.clear();
			return false;
		}
		mapGridReduceNum[nIndex] = nNum;
	}
	return true;
}
//是否存在物品
bool PackagePart::HasBagItem(const LIST_ITEM &lstItem, ORDER_MAP_UINT16_INT32 &mapGridReduceNum, int8_t byPackageType)
{
	if (!ValidPackageType(byPackageType))
	{
		return false;
	}
	mapGridReduceNum.clear();

	MAP_UINT32_INT32 mapHasUnBind;		//非绑定物品
	MAP_UINT32_INT32 mapHasBind;		//绑定物品
	mapHasUnBind.clear();
	mapHasBind.clear();


	//记录物品对应的可堆叠格子当前有的绑定数量
	ORDER_MAP_UINT32_ORDER_MAP_UINT16_INT32 mapItemBindGridHas;
	mapItemBindGridHas.clear();
	//记录物品对应的可堆叠格子当前有的非绑定数量
	ORDER_MAP_UINT32_ORDER_MAP_UINT16_INT32 mapItemUnbindGridHas;
	mapItemUnbindGridHas.clear();

	LIST_ITEM::const_iterator iter = lstItem.begin();
	for (; iter != lstItem.end(); ++iter)
	{
		const SItem &item = (*iter);
		if (item.nNum <= 0)
		{
			continue;
		}

		MAP_UINT32_INT32::iterator iterUnbind = mapHasUnBind.find(item.nItemID);
		if (iterUnbind == mapHasUnBind.end())
		{
			int32_t nUnBindNum = 0;
			int32_t nBindNum = 0;
			ORDER_MAP_UINT16_INT32 mapUnbindHas;
			ORDER_MAP_UINT16_INT32 mapBindHas;
			mapUnbindHas.clear();
			mapBindHas.clear();
			GetBagItemNum(item.nItemID, nUnBindNum, nBindNum, mapUnbindHas, mapBindHas, byPackageType);
			//
			mapHasUnBind[item.nItemID] = nUnBindNum;
			mapHasBind[item.nItemID] = nBindNum;
			mapItemBindGridHas[item.nItemID] = mapBindHas;
			mapItemUnbindGridHas[item.nItemID] = mapUnbindHas;
		}
		if ((int8_t)EBindState::EBindState_no == item.byBind)
		{
			if (mapHasUnBind[item.nItemID] < item.nNum)
			{
				//数量不够
				return false;
			}
			//总数量和非绑定数量变化
			mapHasUnBind[item.nItemID] -= item.nNum;
			//
			int32_t reduceNum = item.nNum;
			ORDER_MAP_UINT16_INT32 &mapUnbindHas = mapItemUnbindGridHas[item.nItemID];
			ORDER_MAP_UINT16_INT32::iterator iterHas = mapUnbindHas.begin();
			for (; iterHas != mapUnbindHas.end(); ++iterHas)
			{
				uint16_t idx = iterHas->first;
				int32_t canReduceNum = iterHas->second;
				if (canReduceNum <= 0)
				{
					continue;
				}
				int32_t idxReduce = 0;
				if (canReduceNum >= reduceNum)
				{
					iterHas->second -= reduceNum;
					idxReduce = reduceNum;
					reduceNum = 0;					
				}
				else
				{
					reduceNum -= canReduceNum;
					idxReduce = canReduceNum;
					iterHas->second -= canReduceNum;
				}

				if (idxReduce > 0)
				{
					ORDER_MAP_UINT16_INT32::iterator iterReduce = mapGridReduceNum.find(idx);
					if (iterReduce != mapGridReduceNum.end())
					{
						iterReduce->second += idxReduce;
					}
					else
					{
						mapGridReduceNum[idx] = idxReduce;
					}
				}

				if (reduceNum <= 0)
				{
					break;
				}
			}
		}
		else if ((int8_t)EBindState::EBindState_bind == item.byBind)
		{
			if (mapHasBind[item.nItemID] < item.nNum)
			{
				//数量不够
				return false;
			}
			//总数量和绑定数量变化
			mapHasBind[item.nItemID] -= item.nNum;

			int32_t reduceNum = item.nNum;
			ORDER_MAP_UINT16_INT32 &mapBindHas = mapItemBindGridHas[item.nItemID];
			ORDER_MAP_UINT16_INT32::iterator iterHas = mapBindHas.begin();
			for (; iterHas != mapBindHas.end(); ++iterHas)
			{
				uint16_t idx = iterHas->first;
				int32_t canReduceNum = iterHas->second;
				if (canReduceNum <= 0)
				{
					continue;
				}
				int32_t idxReduce = 0;
				if (canReduceNum >= reduceNum)
				{
					iterHas->second -= reduceNum;
					idxReduce = reduceNum;
					reduceNum = 0;					
				}
				else
				{
					reduceNum -= canReduceNum;
					idxReduce = canReduceNum;
					iterHas->second -= canReduceNum;
				}

				if (idxReduce > 0)
				{
					ORDER_MAP_UINT16_INT32::iterator iterReduce = mapGridReduceNum.find(idx);
					if (iterReduce != mapGridReduceNum.end())
					{
						iterReduce->second += idxReduce;
					}
					else
					{
						mapGridReduceNum[idx] = idxReduce;
					}
				}

				if (reduceNum <= 0)
				{
					break;
				}
			}
		}
		else
		{
			int32_t nTempNum = item.nNum;
			//先扣除绑定，后非绑定
			if (mapHasBind[item.nItemID] > 0)
			{
				int32_t reduceNum = 0;
				if (mapHasBind[item.nItemID] >= nTempNum)
				{
					mapHasBind[item.nItemID] -= nTempNum;
					reduceNum = nTempNum;
					nTempNum = 0;
				}
				else
				{
					nTempNum -= mapHasBind[item.nItemID];
					reduceNum = mapHasBind[item.nItemID];
					mapHasBind[item.nItemID] = 0;
				}

				if (reduceNum > 0)
				{
					ORDER_MAP_UINT16_INT32 &mapBindHas = mapItemBindGridHas[item.nItemID];
					ORDER_MAP_UINT16_INT32::iterator iterHas = mapBindHas.begin();
					for (; iterHas != mapBindHas.end(); ++iterHas)
					{
						uint16_t idx = iterHas->first;
						int32_t canReduceNum = iterHas->second;
						if (canReduceNum <= 0)
						{
							continue;
						}
						int32_t idxReduce = 0;
						if (canReduceNum >= reduceNum)
						{
							iterHas->second -= reduceNum;
							idxReduce = reduceNum;
							reduceNum = 0;							
						}
						else
						{
							reduceNum -= canReduceNum;
							idxReduce = canReduceNum;
							iterHas->second -= canReduceNum;
						}

						if (idxReduce > 0)
						{
							ORDER_MAP_UINT16_INT32::iterator iterReduce = mapGridReduceNum.find(idx);
							if (iterReduce != mapGridReduceNum.end())
							{
								iterReduce->second += idxReduce;
							}
							else
							{
								mapGridReduceNum[idx] = idxReduce;
							}
						}

						if (reduceNum <= 0)
						{
							break;
						}
					}
				}
			}
			if (nTempNum > 0)
			{
				if (mapHasUnBind[item.nItemID] > 0)
				{
					int32_t reduceNum = 0;
					if (mapHasUnBind[item.nItemID] >= nTempNum)
					{
						mapHasUnBind[item.nItemID] -= nTempNum;
						reduceNum = nTempNum;
						nTempNum = 0;
					}
					else
					{
						nTempNum -= mapHasUnBind[item.nItemID];
						reduceNum = mapHasUnBind[item.nItemID];
						mapHasUnBind[item.nItemID] = 0;
					}

					if (reduceNum > 0)
					{
						ORDER_MAP_UINT16_INT32 &mapUnbindHas = mapItemUnbindGridHas[item.nItemID];
						ORDER_MAP_UINT16_INT32::iterator iterHas = mapUnbindHas.begin();
						for (; iterHas != mapUnbindHas.end(); ++iterHas)
						{
							uint16_t idx = iterHas->first;
							int32_t canReduceNum = iterHas->second;
							if (canReduceNum <= 0)
							{
								continue;
							}
							int32_t idxReduce = 0;
							if (canReduceNum >= reduceNum)
							{
								iterHas->second -= reduceNum;
								idxReduce = reduceNum;
								reduceNum = 0;
								
							}
							else
							{
								reduceNum -= canReduceNum;
								idxReduce = canReduceNum;
								iterHas->second -= canReduceNum;
							}

							if (idxReduce > 0)
							{
								ORDER_MAP_UINT16_INT32::iterator iterReduce = mapGridReduceNum.find(idx);
								if (iterReduce != mapGridReduceNum.end())
								{
									iterReduce->second += idxReduce;
								}
								else
								{
									mapGridReduceNum[idx] = idxReduce;
								}
							}

							if (reduceNum <= 0)
							{
								break;
							}
						}
					}
				}
			}
			if (nTempNum > 0)
			{
				//还有剩余的，//数量不够
				return false;
			}
		}
	}
	return true;
}

//移除物品
bool PackagePart::RemoveBagItem(ORDER_MAP_UINT16_INT32 &mapGridReduceNum, MAP_UINT32_INT32 &mapItemNum, int8_t byPackageType)
{
	if (!ValidPackageType(byPackageType))
	{
		return false;
	}
	PackageUpdateRet protoRet;
	StorageUpdateRsp protoStorageRet;
	ORDER_MAP_UINT16_INT32::iterator iterIdx = mapGridReduceNum.begin();
	for (; iterIdx != mapGridReduceNum.end(); ++iterIdx)
	{
		uint16_t idx = iterIdx->first;
		int32_t reduceNum = iterIdx->second;
		if (reduceNum <= 0)
		{
			continue;
		}
		CItemBase *pItem = GetItemByPackageType(byPackageType,idx);
		if (nullptr == pItem)
		{
			continue;
		}
		pItem->AddNum(-reduceNum);
		if (EPackageType_packge == byPackageType)
		{
			AddPackageUpdateInfo(pItem, protoRet);
		}
		else
		{
			AddStorageUpdateInfo(pItem, protoStorageRet);
		}
		bool flag = true;
		uint32_t nItemId = pItem->GetItemID();
		if (0 == pItem->GetNum())
		{
			if (idx == SetItemByPackageType(byPackageType, idx, nullptr))
			{
				g_GetItemMgr()->FreeItemObj(pItem);
			}
			else
			{
				flag = false;
				LogErrFmtPrint("[logic] PackagePart::RemoveBagItem....SetItemByPackageType failed...idx:%d, byPackageType:%d ", idx, byPackageType);
			}
		}
		if (flag)
		{
			MAP_UINT32_INT32::iterator iterItem = mapItemNum.find(nItemId);
			if (iterItem != mapItemNum.end())
			{
				iterItem->second += reduceNum;
			}
			else
			{
				mapItemNum[nItemId] = reduceNum;
			}
		}		
	}
	if (EPackageType_packge == byPackageType)
	{
		UpdatePackageInfo(protoRet);
	}
	else
	{
		StorageUpdate(protoStorageRet);
	}
	return true;
}

//背包是否存在物品
bool PackagePart::HasPackageItem(const LIST_ITEM &lstItem, ORDER_MAP_UINT16_INT32 &mapGridReduceNum)
{
	return HasBagItem(lstItem, mapGridReduceNum, EPackageType_packge);
}
//背包是否存在物品
bool PackagePart::HasPackageItem(const MAP_UINT16_INT32 &mapIdxNum, ORDER_MAP_UINT16_INT32 &mapGridReduceNum)
{
	return HasBagItem(mapIdxNum, mapGridReduceNum,EPackageType_packge);
}
//仓库是否存在物品
bool PackagePart::HasStorageItem(const LIST_ITEM &lstItem, ORDER_MAP_UINT16_INT32 &mapGridReduceNum)
{
	return HasBagItem(lstItem, mapGridReduceNum, EPackageType_storage);
}
//仓库是否存在物品
bool PackagePart::HasStorageItem(const MAP_UINT16_INT32 &mapIdxNum, ORDER_MAP_UINT16_INT32 &mapGridReduceNum)
{
	return HasBagItem(mapIdxNum, mapGridReduceNum, EPackageType_storage);
}
//移除背包物品
bool PackagePart::RemovePackageItem(ORDER_MAP_UINT16_INT32 &mapGridReduceNum,MAP_UINT32_INT32 &mapItemNum)
{
	return RemoveBagItem(mapGridReduceNum, mapItemNum, EPackageType_packge);
}
//移除仓库物品
bool PackagePart::RemoveSotrageItem(ORDER_MAP_UINT16_INT32 &mapGridReduceNum,MAP_UINT32_INT32 &mapItemNum)
{
	return RemoveBagItem(mapGridReduceNum, mapItemNum, EPackageType_storage);
}

//移除物品事件处理
void PackagePart::OnRemoveItemEvent(MAP_UINT32_INT32 &mapItemNum, SItemSourceParam &sourceParam)
{
	//移除物品 任务事件
	MAP_UINT32_INT32 mapCollect;
	mapCollect.clear();
	MAP_UINT32_INT32::iterator iterRemove = mapItemNum.begin();
	for (; iterRemove != mapItemNum.end(); ++iterRemove)
	{
		if (iterRemove->second <= 0)
		{
			continue;
		}
		AddCollectItem(iterRemove->first, -iterRemove->second, mapCollect);
	}
	CollectItemEvent(mapCollect, sourceParam, EItemOpetateType_Del);
}

//获取标签页空格子索引列表
bool PackagePart::GetEmptyGrid(uint8_t byLabel, VEC_UINT16 &vecGrid, uint16_t nNum /*= 0*/)
{
	//
	uint16_t nStartIndex = GetLabelStartIdx(byLabel);
	uint16_t nEndIndex = GetLabelEndIdx(byLabel);
	if (!ValidIndex(nStartIndex) || !ValidIndex(nEndIndex))
	{
		MMOLOG_FMT_ERROR("[logic] PackagePart::GetEmptyGrid,index not valid,  nStartIndex[%d] nEndIndex[%d]...byLabel[%d] cid[%u]", nStartIndex, nEndIndex, byLabel, m_pMaster->GetCid());
		return false;
	}
	for (size_t i = nStartIndex; i <= nEndIndex; ++i)
	{
		if (nullptr == GetItemByIndex(i))
		{
			vecGrid.push_back(i);
		}
		if (nNum > 0 && vecGrid.size() >= (size_t)nNum)
		{
			break;
		}
	}

	if (nNum > 0)
	{
		if (vecGrid.size() >= (size_t)nNum)
		{
			return true;
		}
		//格子不够，清空下
		vecGrid.clear();
		return false;
	}
	
	return true;
}

//获取某个物品剩余可叠加的数量
int32_t PackagePart::GetItemLeftPile(uint32_t nItemID, int32_t &nUnBindNum, int32_t &nBindNum, ORDER_MAP_UINT16_INT32 &mapUnbindGridHas, ORDER_MAP_UINT16_INT32 &mapBindGridHas, int8_t byPackageType)
{
	nUnBindNum = 0;
	nBindNum = 0;
	mapUnbindGridHas.clear();
	mapBindGridHas.clear();
	if (!ValidPackageType(byPackageType))
	{
		return 0;
	}
	int32_t stackLimit = 1;
	uint8_t byLabel = EPackageLabel_none;
	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(nItemID);
	if (nullptr == pItemCfg)
	{
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(nItemID);
		if (nullptr == pEquipCfg)
		{
			LogErrFmtPrint("[logic] GetItemLeftPile...can not find item cfg ...nItemID[%u] ", nItemID);
			return 0;
		}
		//装备是不允许有叠加的，所以这里直接返回
		return 0;
	}
	else
	{
		stackLimit = g_GetItemMgr()->ItemMaxPile(pItemCfg);
		byLabel = g_GetItemMgr()->GetPackageLabel(pItemCfg);
	}

	return GetLabelItemLeftPile(byLabel, nItemID, stackLimit, nUnBindNum, nBindNum, mapUnbindGridHas,mapBindGridHas,byPackageType);
}

//获取某个标签内物品剩余可叠加数量
int32_t PackagePart::GetLabelItemLeftPile(uint8_t byLabel, uint32_t nItemID, int32_t stackLimit, int32_t &nUnBindNum, int32_t &nBindNum, ORDER_MAP_UINT16_INT32 &mapUnbindGridHas, ORDER_MAP_UINT16_INT32 &mapBindGridHas,int8_t byPackageType)
{
	nUnBindNum = 0;
	nBindNum = 0;
	//vecUnBindItem.clear();
	//vecBindItem.clear();
	mapUnbindGridHas.clear();
	mapBindGridHas.clear();
	if (!ValidLabel(byLabel) || !ValidPackageType(byPackageType))
	{
		return 0;
	}
	uint16_t nStartIndex = GetLabelStartIdxByPackageType(byLabel, byPackageType);//	GetLabelStartIdx(byLabel);
	uint16_t nEndIndex = GetLabelEndIdxByPackageType(byLabel, byPackageType);//GetLabelEndIdx(byLabel);
	/*if (!ValidIndex(nStartIndex) || !ValidIndex(nEndIndex))
	{
		MMOLOG_FMT_ERROR("[logic] index not valid ,byLabel[%d] nStartIndex[%d] nEndIndex[%d]", byLabel,nStartIndex, nEndIndex);
		return 0;
	}*/
	if (!ValidIndexByPackageType(nStartIndex, byPackageType) || !ValidIndexByPackageType(nEndIndex,byPackageType))
	{
		MMOLOG_FMT_ERROR("[logic] index not valid ,byLabel[%d] nStartIndex[%d] nEndIndex[%d], byPackageType:%d ", byLabel,nStartIndex, nEndIndex,byPackageType);
		return 0;
	}
	//
	for (size_t i = nStartIndex; i <= nEndIndex; ++i)
	{
		CItemBase *pItem = GetItemByPackageType(byPackageType, i);//GetItemByIndex(i);
		if (nullptr != pItem && nItemID == pItem->GetItemID())
		{
			int8_t byBind = pItem->GetBind();
			int32_t nPile = (int32_t)pItem->GetNum();
			if (nPile < stackLimit)
			{
				if ((uint8_t)EBindState::EBindState_no == byBind)
				{
					nUnBindNum += (stackLimit - nPile);
					//vecUnBindItem.push_back(pItem);
					mapUnbindGridHas[pItem->GetIndex()] = nPile;
				}
				else if ((uint8_t)EBindState::EBindState_bind == byBind)
				{
					nBindNum += (stackLimit - nPile);
					//vecBindItem.push_back(pItem);
					mapBindGridHas[pItem->GetIndex()] = nPile;
				}
			}			
		}
	}
	return (nUnBindNum + nBindNum);
}
//合并背包物品列表
void PackagePart::MergePackageItemList(LIST_ITEM &inlstItem, VEC_ITEM_PROTO_EX &vecinProtoEx, MAP_LABEL_LIST_ITEM_EX &mapOutLabelItem, MAP_LABEL_VEC_ITEM_PROTO_EX &mapOutLabelVecItemProtoEx)
{
	return MergeItemList(inlstItem, vecinProtoEx, mapOutLabelItem, mapOutLabelVecItemProtoEx, EPackageType_packge);
}
//合并仓库物品列表
void PackagePart::MergeStorageItemList(LIST_ITEM &inlstItem, VEC_ITEM_PROTO_EX &vecinProtoEx, MAP_LABEL_LIST_ITEM_EX &mapOutLabelItem, MAP_LABEL_VEC_ITEM_PROTO_EX &mapOutLabelVecItemProtoEx)
{
	return MergeItemList(inlstItem, vecinProtoEx, mapOutLabelItem, mapOutLabelVecItemProtoEx, EPackageType_storage);
}
//合并物品列表
void PackagePart::MergeItemList(LIST_ITEM &inlstItem, VEC_ITEM_PROTO_EX &vecinProtoEx, MAP_LABEL_LIST_ITEM_EX &mapOutLabelItem, MAP_LABEL_VEC_ITEM_PROTO_EX &mapOutLabelVecItemProtoEx, int8_t byPackageType/* = EPackageType_packge*/)
{
	if (!ValidPackageType(byPackageType))
	{
		return;
	}
	mapOutLabelItem.clear();
	mapOutLabelVecItemProtoEx.clear();
	//
	MAP_LABEL_LIST_ITEM_EX mapLabelNoPileItemEx;//不可堆叠物品
	mapLabelNoPileItemEx.clear();
	LIST_ITEM::const_iterator iter = inlstItem.begin();
	for (; iter != inlstItem.end(); ++iter)
	{
		const SItem &in = (*iter);
		if (in.nItemID == 0)
		{
			continue;
		}
		uint8_t byType = EItemType_common;
		int8_t byBind = (int8_t)EBindState::EBindState_no;
		int32_t maxPile = 0;
		uint8_t byLabel = EPackageLabel_none;
		const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(in.nItemID);
		if (nullptr == pItemCfg)
		{
			const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(in.nItemID);
			if (nullptr == pEquipCfg)
			{
				MMOLOG_FMT_ERROR("[logic] nullptr == pEquipCfg, itemid:%u ", in.nItemID);
				continue;
			}
			byType = EItemType_equip;
			byBind = g_GetItemMgr()->BindStateByAdd(pEquipCfg, in.byBind);
			maxPile = g_GetItemMgr()->ItemMaxPile(pEquipCfg);
			byLabel = g_GetItemMgr()->GetPackageLabel(pEquipCfg);
		}
		else
		{
			byType = EItemType_common;
			byBind = g_GetItemMgr()->BindStateByAdd(pItemCfg, in.byBind);
			maxPile = g_GetItemMgr()->ItemMaxPile(pItemCfg);
			byLabel = g_GetItemMgr()->GetPackageLabel(pItemCfg);
		}
		//
		if (byBind != (int8_t)EBindState::EBindState_no && byBind != (int8_t)EBindState::EBindState_bind)
		{
			LogErrFmtPrint("[logic] MergeItemList bind state error ,itemid[%u],num[%d], bybind[%d] ", in.nItemID, in.nNum, byBind);
			continue;
		}
		if (maxPile <= 0)
		{
			LogErrFmtPrint("[logic] MergeItemList maxPile error ,itemid[%u],num[%d], bybind[%d], maxPile:%d ", in.nItemID, in.nNum, byBind, maxPile);
			continue;
		}
		if (!ValidLabel(byLabel))
		{
			LogErrFmtPrint("[logic] MergeItemList ValidLabel error ,itemid[%u],num[%d], bybind[%d], maxPile:%d, byLabel:%d ", in.nItemID, in.nNum, byBind, maxPile, byLabel);
			continue;
		}
		LIST_ITEM_EX *pLstLabelItem = nullptr;
		MAP_LABEL_LIST_ITEM_EX::iterator iterLabelItem = mapOutLabelItem.find(byLabel);
		if (iterLabelItem == mapOutLabelItem.end())
		{
			LIST_ITEM_EX lstOutItem;
			lstOutItem.clear();
			mapOutLabelItem[byLabel] = lstOutItem;
			pLstLabelItem = &mapOutLabelItem[byLabel];
		}
		else
		{
			pLstLabelItem = &iterLabelItem->second;
		}

		if (EItemType_equip == byType || 1 == maxPile) //装备或者 不可堆叠物品
		{
			LIST_ITEM_EX *pLstLabelNoPileItem = nullptr;
			MAP_LABEL_LIST_ITEM_EX::iterator iterLabelNoPile = mapLabelNoPileItemEx.find(byLabel);
			if (iterLabelNoPile == mapLabelNoPileItemEx.end())
			{
				LIST_ITEM_EX lstOutItem;
				lstOutItem.clear();
				mapLabelNoPileItemEx[byLabel] = lstOutItem;
				pLstLabelNoPileItem = &mapLabelNoPileItemEx[byLabel];
			}
			else
			{
				pLstLabelNoPileItem = &iterLabelNoPile->second;
			}
			
			for (int32_t i = 0; i < in.nNum; ++i)
			{
				SItemEx equip;
				equip.nItemID = in.nItemID;
				equip.nNum = 1;
				equip.byBind = byBind;
				equip.stackNum = maxPile;
				equip.byType = byType;
				pLstLabelNoPileItem->push_back(equip);
			}

			continue;
		}

		//非装备并且可堆叠物品
		bool bFlag = false;
		LIST_ITEM_EX::iterator iterout = pLstLabelItem->begin();
		for (; iterout != pLstLabelItem->end(); ++iterout)
		{
			SItemEx &out = (*iterout);
			if (out.nItemID == in.nItemID && out.byBind == byBind)
			{
				out.nNum += in.nNum;
				bFlag = true;
				break;
			}
		}
		if (!bFlag)
		{
			SItemEx itemEx;
			itemEx.nItemID = in.nItemID;
			itemEx.nNum = in.nNum;
			itemEx.byBind = byBind;
			itemEx.stackNum = maxPile;
			itemEx.byType = byType;
			//这里校验下堆叠数
			pLstLabelItem->push_back(itemEx);
			int32_t isize = pLstLabelItem->size();
			if (isize > 0)				
			{
				isize = isize;
			}
		}
	} // end of for (; iter != inlstItem.end(); ++iter)

	//处理不可堆叠物品
	MAP_LABEL_LIST_ITEM_EX::iterator iterNoPile = mapLabelNoPileItemEx.begin();
	for (; iterNoPile != mapLabelNoPileItemEx.end(); ++iterNoPile)
	{
		uint8_t byLabel = iterNoPile->first;
		LIST_ITEM_EX &lstNoPileItemEx = iterNoPile->second;
		LIST_ITEM lstNoPileItem;
		lstNoPileItem.clear();
		LIST_ITEM_EX::iterator iterEx = lstNoPileItemEx.begin();
		for (; iterEx != lstNoPileItemEx.end(); ++iterEx)
		{
			SItemEx &itemEx = (*iterEx);
			SItem item(itemEx.nItemID, itemEx.nNum, itemEx.byBind);
			lstNoPileItem.push_back(item);
		}
		VEC_ITEM_PROTO_EX *pVecProtoEx = nullptr;
		MAP_LABEL_VEC_ITEM_PROTO_EX::iterator iterA = mapOutLabelVecItemProtoEx.find(byLabel);
		if (iterA == mapOutLabelVecItemProtoEx.end())
		{
			VEC_ITEM_PROTO_EX vecItemProtoA;
			vecItemProtoA.clear();
			mapOutLabelVecItemProtoEx[byLabel] = vecItemProtoA;
			pVecProtoEx = &mapOutLabelVecItemProtoEx[byLabel];
		}
		else
		{
			pVecProtoEx = &iterA->second;
		}
		//
		SItemCond itemCond;
		g_GetDropMgr()->GetItemCond(dynamic_cast<Player*>(m_pMaster), itemCond);
		g_GetItemMgr()->CreateItem(lstNoPileItem, *pVecProtoEx, itemCond, false);
	}


	//
	VEC_ITEM_PROTO_EX::iterator iterProto = vecinProtoEx.begin();
	for (; iterProto != vecinProtoEx.end(); ++iterProto)
	{
		const ItemProtoInfo &proto = (*iterProto);
		//
		uint8_t byType = EItemType_common;
		int8_t byBind = (int8_t)EBindState::EBindState_no;
		int32_t maxPile = 0;
		uint8_t byLabel = EPackageLabel_none;
		const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(proto.item_id());
		if (nullptr == pItemCfg)
		{
			const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(proto.item_id());
			if (nullptr == pEquipCfg)
			{
				MMOLOG_FMT_ERROR("[logic] nullptr == pEquipCfg, itemid:%u ", proto.item_id());
				continue;
			}
			byType = EItemType_equip;
			byBind = g_GetItemMgr()->BindStateByAdd(pEquipCfg, proto.bind());
			maxPile = g_GetItemMgr()->ItemMaxPile(pEquipCfg);
			byLabel = g_GetItemMgr()->GetPackageLabel(pEquipCfg);
		}
		else
		{
			byType = EItemType_common;
			byBind = g_GetItemMgr()->BindStateByAdd(pItemCfg, proto.bind());
			maxPile = g_GetItemMgr()->ItemMaxPile(pItemCfg);
			byLabel = g_GetItemMgr()->GetPackageLabel(pItemCfg);
		}
		//
		if (byBind != (int8_t)EBindState::EBindState_no && byBind != (int8_t)EBindState::EBindState_bind)
		{
			MMOLOG_FMT_ERROR("[logic] MergeItemList bind state error ,itemid[%u],num[%d], bybind[%d] ", proto.item_id(), proto.item_num(), byBind);
			continue;
		}
		if (maxPile <= 0)
		{
			LogErrFmtPrint("[logic] MergeItemList maxPile error ,itemid[%u],num[%d], bybind[%d], maxPile:%d ", proto.item_id(), proto.item_num(), byBind, maxPile);
			continue;
		}
		if (!ValidLabel(byLabel))
		{
			LogErrFmtPrint("[logic] MergeItemList ValidLabel error ,itemid[%u],num[%d], bybind[%d], maxPile:%d , byLabel:%d", proto.item_id(), proto.item_num(), byBind, maxPile,byLabel);
			continue;
		}
		/*
		这里需要处理下 玩家可以改变属性的物品，比如 所有的装备,血包，星魂传送物品，藏宝图，跑商商券等
		此类物品必须是不可堆叠物品
		*/
		if (EItemType_equip == byType || 1 == maxPile)
		{
			ItemProtoInfo newproto(proto);
			newproto.set_bind(byBind);
			//
			VEC_ITEM_PROTO_EX *pVecProtoEx = nullptr;
			MAP_LABEL_VEC_ITEM_PROTO_EX::iterator iterA = mapOutLabelVecItemProtoEx.find(byLabel);
			if (iterA == mapOutLabelVecItemProtoEx.end())
			{
				VEC_ITEM_PROTO_EX vecItemProtoA;
				vecItemProtoA.clear();
				mapOutLabelVecItemProtoEx[byLabel] = vecItemProtoA;
				pVecProtoEx = &mapOutLabelVecItemProtoEx[byLabel];
			}
			else
			{
				pVecProtoEx = &iterA->second;
			}
			pVecProtoEx->push_back(newproto);
		}
		else
		{
			LIST_ITEM_EX *pLstLabelItem = nullptr;
			MAP_LABEL_LIST_ITEM_EX::iterator iterLabelItem = mapOutLabelItem.find(byLabel);
			if (iterLabelItem == mapOutLabelItem.end())
			{
				LIST_ITEM_EX lstOutItem;
				lstOutItem.clear();
				mapOutLabelItem[byLabel] = lstOutItem;
				pLstLabelItem = &mapOutLabelItem[byLabel];
			}
			else
			{
				pLstLabelItem = &iterLabelItem->second;
			}
			//
			bool bFlag = false;
			LIST_ITEM_EX::iterator iterout = pLstLabelItem->begin();
			for (; iterout != pLstLabelItem->end(); ++iterout)
			{
				SItemEx &out = (*iterout);
				if (out.nItemID == proto.item_id() && out.byBind == byBind)
				{
					out.nNum += proto.item_num();
					bFlag = true;
					break;
				}
			}
			if (!bFlag)
			{
				SItemEx item;
				item.nItemID = proto.item_id();
				item.nNum = proto.item_num();
				item.byBind = byBind;
				item.stackNum = maxPile;
				item.byType = byType;
				//这里校验下堆叠数
				pLstLabelItem->push_back(item);
			}
		} // end of if (1 == maxPile)
	} // end of for (; iterProto != vecinProtoEx.end(); ++iterProto)
}
//能否添加进背包
bool PackagePart::CanPackageAddItem(MAP_LABEL_LIST_ITEM_EX &mapInLabelItem, MAP_LABEL_VEC_ITEM_PROTO_EX &mapInLabelVecItemProtoEx, MAP_UINT16_INT32 &mapOutGridAddNum, MAP_INDEX_ITEM_PROTO_EX &mapOutNewIdxItemProtoEx)
{
	return CanBagAddItem(mapInLabelItem, mapInLabelVecItemProtoEx, mapOutGridAddNum, mapOutNewIdxItemProtoEx, EPackageType_packge);
}
//仓库能否加物品
bool PackagePart::CanStorageAddItem(MAP_LABEL_LIST_ITEM_EX &mapInLabelItem, MAP_LABEL_VEC_ITEM_PROTO_EX &mapInLabelVecItemProtoEx, MAP_UINT16_INT32 &mapOutGridAddNum, MAP_INDEX_ITEM_PROTO_EX &mapOutNewIdxItemProtoEx)
{
	return CanBagAddItem(mapInLabelItem, mapInLabelVecItemProtoEx, mapOutGridAddNum, mapOutNewIdxItemProtoEx, EPackageType_storage);
}
//能否添加到背包
bool PackagePart::CanBagAddItem(MAP_LABEL_LIST_ITEM_EX &mapInLabelItem, MAP_LABEL_VEC_ITEM_PROTO_EX &mapInLabelVecItemProtoEx, MAP_UINT16_INT32 &mapOutGridAddNum, MAP_INDEX_ITEM_PROTO_EX &mapOutNewIdxItemProtoEx, int8_t byPackageType)
{
	if (!ValidPackageType(byPackageType))
	{
		return false;
	}
	//每个标签页剩余格子数
	MAP_INT8_VEC_UINT16 mapLabelVecGrid;
	mapLabelVecGrid.clear();	
	//out 参数先clear
	mapOutNewIdxItemProtoEx.clear();
	mapOutGridAddNum.clear();
	//统计每个标签页可堆叠物品的数量（绑定，非绑定，总数量）
	MAP_INT8_MAP_UINT32_INT32 mapLabelUnbindItem;
	MAP_INT8_MAP_UINT32_INT32 mapLabelBindItem;
	//可堆叠的物品，把可堆叠的格子放满之后，还需要新的格子
	MAP_INDEX_ITEM mapIndexItem;
	mapIndexItem.clear();
	

	//记录物品对应的可堆叠格子当前有的绑定数量
	ORDER_MAP_UINT32_ORDER_MAP_UINT16_INT32 mapItemBindGridHas; 
	mapItemBindGridHas.clear();
	//记录物品对应的可堆叠格子当前有的非绑定数量
	ORDER_MAP_UINT32_ORDER_MAP_UINT16_INT32 mapItemUnbindGridHas;
	mapItemUnbindGridHas.clear();

	//仓库的话，先找出所有的空格子备用
	VEC_UINT16 vecStorgeNewGrid;
	vecStorgeNewGrid.clear();
	if (EPackageType_storage == byPackageType)
	{
		GetStorageEmptyGrid(vecStorgeNewGrid);
	}

	//标签页可堆叠物品处理
	MAP_LABEL_LIST_ITEM_EX::iterator iterLabel = mapInLabelItem.begin();
	for (; iterLabel != mapInLabelItem.end(); ++iterLabel)
	{
		int8_t byLabel = iterLabel->first;
		LIST_ITEM_EX &lstInItemEx = iterLabel->second;
		//label 物品数量（绑定）
		MAP_UINT32_INT32 *pLabelBindItem = nullptr;
		MAP_INT8_MAP_UINT32_INT32::iterator iterLabelB = mapLabelBindItem.find(byLabel);
		if (iterLabelB == mapLabelBindItem.end())
		{
			MAP_UINT32_INT32 mapBindItem;
			mapLabelBindItem[byLabel] = mapBindItem;
			pLabelBindItem = &mapLabelBindItem[byLabel];
		}
		else
		{
			pLabelBindItem = &iterLabelB->second;
		}
		//label 物品数量（非绑定）
		MAP_UINT32_INT32 *pLabelUnbindItem = nullptr;
		MAP_INT8_MAP_UINT32_INT32::iterator iterLabelC = mapLabelUnbindItem.find(byLabel);
		if (iterLabelC == mapLabelUnbindItem.end())
		{
			MAP_UINT32_INT32 mapUnbindItem;
			mapLabelUnbindItem[byLabel] = mapUnbindItem;
			pLabelUnbindItem = &mapLabelUnbindItem[byLabel];
		}
		else
		{
			pLabelUnbindItem = &iterLabelC->second;
		}
		//标签页剩余格子数
		VEC_UINT16 *pLabelNewGrid = nullptr;
		if (EPackageType_packge == byPackageType)
		{
			MAP_INT8_VEC_UINT16::iterator iterLabelGrid = mapLabelVecGrid.find(byLabel);
			if (iterLabelGrid == mapLabelVecGrid.end())
			{
				VEC_UINT16 vecNewGrid;
				vecNewGrid.clear();
				GetEmptyGrid(byLabel, vecNewGrid);
				mapLabelVecGrid[byLabel] = vecNewGrid;
				pLabelNewGrid = &mapLabelVecGrid[byLabel];
			}
			else
			{
				pLabelNewGrid = &iterLabelGrid->second;
			}
		}
		else
		{
			pLabelNewGrid = &vecStorgeNewGrid;
		}
		

		//
		MAP_UINT32_INT32 &mapUnBind = *pLabelUnbindItem;
		MAP_UINT32_INT32 &mapBind = *pLabelBindItem;
		VEC_UINT16 &vecEmptyGrid = *pLabelNewGrid;

		//统计每个标签页剩余可叠加的物品数量
		LIST_ITEM_EX::iterator iterInItem = lstInItemEx.begin();
		for (; iterInItem != lstInItemEx.end();++iterInItem)
		{
			SItemEx &item = (*iterInItem);
			MAP_UINT32_INT32::iterator iterBind = mapBind.find(item.nItemID);
			if (iterBind == mapBind.end())
			{
				int32_t unbindNum = 0;
				int32_t bindNum = 0;
				//VEC_PACKAGE_ITEM vecUnbindItem;
				//vecUnbindItem.clear();
				//VEC_PACKAGE_ITEM vecBindItem;
				//vecBindItem.clear();
				ORDER_MAP_UINT16_INT32 mapUnbindGridHas;
				mapUnbindGridHas.clear();
				ORDER_MAP_UINT16_INT32 mapBindGridHas;
				mapBindGridHas.clear();
				GetItemLeftPile(item.nItemID, unbindNum, bindNum, /*vecUnbindItem, vecBindItem,*/ mapUnbindGridHas, mapBindGridHas, byPackageType);
				//
				mapUnBind[item.nItemID] = unbindNum;
				mapBind[item.nItemID] = bindNum;
				mapItemBindGridHas[item.nItemID] = mapBindGridHas;
				mapItemUnbindGridHas[item.nItemID] = mapUnbindGridHas;
			}

			//增加的数量是否能放到 可堆叠的物品格子中
			int32_t nLeft = 0;
			int32_t addNum = 0;
			if ((int8_t)EBindState::EBindState_no == item.byBind)
			{
				if (mapUnBind[item.nItemID] >= item.nNum)
				{
					mapUnBind[item.nItemID] -= item.nNum;
					addNum = item.nNum;
				}
				else
				{
					nLeft = item.nNum - mapUnBind[item.nItemID];
					addNum = mapUnBind[item.nItemID];
					mapUnBind[item.nItemID] = 0;
				}
				if (addNum > 0)
				{
					ORDER_MAP_UINT16_INT32 &mapUnbindGridHas = mapItemUnbindGridHas[item.nItemID];
					ORDER_MAP_UINT16_INT32::iterator iterHas = mapUnbindGridHas.begin();
					for (; iterHas != mapUnbindGridHas.end(); ++iterHas)
					{
						uint16_t idx = iterHas->first;
						int32_t has = iterHas->second;
						int32_t canAddNum = item.stackNum - has;
						if (canAddNum <= 0)
						{
							continue;
						}
						int32_t idxAdd = 0;
						if (canAddNum >= addNum)
						{
							iterHas->second += addNum;
							idxAdd = addNum;
							addNum = 0;							
						}
						else
						{
							addNum -= canAddNum;
							idxAdd = canAddNum;
							iterHas->second += canAddNum;
						}

						if (idxAdd > 0)
						{
							MAP_UINT16_INT32::iterator iterAdd = mapOutGridAddNum.find(idx);
							if (iterAdd != mapOutGridAddNum.end())
							{
								iterAdd->second += idxAdd;
							}
							else
							{
								mapOutGridAddNum[idx] = idxAdd;
							}
						}
						


						if (addNum <= 0)
						{
							break;
						}
					}

					if (addNum > 0)
					{
						//正常不会走到这里，做一次打印，便于以后定位
						LogErrFmtPrint("[logic] PackagePart::CanPackageAddItem..unbind....addNum > 0...addNum:%d ", addNum);
					}
				}
				
			}
			else if ((int8_t)EBindState::EBindState_bind == item.byBind)
			{
				if (mapBind[item.nItemID] >= item.nNum)
				{
					mapBind[item.nItemID] -= item.nNum;
					addNum = item.nNum;
				}
				else
				{
					nLeft = item.nNum - mapBind[item.nItemID];
					addNum = mapBind[item.nItemID];
					mapBind[item.nItemID] = 0;
				}
				if (addNum > 0)
				{
					ORDER_MAP_UINT16_INT32 &mapBindGridHas = mapItemBindGridHas[item.nItemID];
					ORDER_MAP_UINT16_INT32::iterator iterHas = mapBindGridHas.begin();
					for (; iterHas != mapBindGridHas.end(); ++iterHas)
					{
						uint16_t idx = iterHas->first;
						int32_t has = iterHas->second;
						int32_t canAddNum = item.stackNum - has;
						if (canAddNum <= 0)
						{
							continue;
						}
						int32_t idxAdd = 0;
						if (canAddNum >= addNum)
						{
							idxAdd = addNum;
							iterHas->second += addNum;
							addNum = 0;
						}
						else
						{
							addNum -= canAddNum;
							idxAdd = canAddNum;
							iterHas->second += canAddNum;
						}

						if (idxAdd > 0)
						{
							MAP_UINT16_INT32::iterator iterAdd = mapOutGridAddNum.find(idx);
							if (iterAdd != mapOutGridAddNum.end())
							{
								iterAdd->second += idxAdd;
							}
							else
							{
								mapOutGridAddNum[idx] = idxAdd;
							}
						}
						

						if (addNum <= 0)
						{
							break;
						}
					}
					if (addNum > 0)
					{
						//正常不会走到这里，做一次打印，便于以后定位
						LogErrFmtPrint("[logic] PackagePart::CanPackageAddItem..bind....addNum > 0...addNum:%d ", addNum);
					}
				}
				
			}

			if (nLeft > 0) //可堆叠的格子放完之后剩下的数量
			{
				int32_t stackLimit = item.stackNum;
				MAP_INDEX_ITEM::iterator iterMap = mapIndexItem.begin();
				for (; iterMap != mapIndexItem.end(); ++iterMap)
				{
					SItem &itemex = iterMap->second;
					if (itemex.nItemID == item.nItemID
						&& itemex.byBind == item.byBind
						&& itemex.nNum < stackLimit
						)
					{
						if (itemex.nNum + nLeft <= stackLimit)
						{
							itemex.nNum += nLeft;
							nLeft = 0;
						}
						else
						{
							uint16_t nCnt = stackLimit - itemex.nNum;
							nLeft -= nCnt;
							itemex.nNum = stackLimit;
						}
					}
					if (nLeft <= 0)
					{
						break;
					}
				} // end of for (; iterMap != mapIndexItem.end(); ++iter)

				if (nLeft > 0) //需要额外分配格子
				{
					uint16_t nCount = 0;  //需要的格子数
					uint16_t nNumEx = 0;  //物品额外剩余数量
					nCount = nLeft / stackLimit;
					nNumEx = nLeft % stackLimit;
					//实际需要格子数
					uint16_t nRealCount = nCount;
					if (nNumEx > 0)
					{
						nRealCount += 1;
					}
					if (vecEmptyGrid.size() < nRealCount)
					{
						//格子不够
						return false;
					}
					for (uint16_t i = 0; i < nCount; ++i)
					{
						VEC_UINT16::iterator iterVec = vecEmptyGrid.begin();
						uint16_t idx = (*iterVec);
						SItem newitem;
						newitem.nItemID = item.nItemID;
						newitem.byBind = item.byBind;
						newitem.nNum = stackLimit;
						//
						mapIndexItem[idx] = newitem;
						vecEmptyGrid.erase(iterVec);
					}
					if (nNumEx > 0)
					{
						//只有可堆叠的才会走到这里
						VEC_UINT16::iterator iterVec = vecEmptyGrid.begin();
						uint16_t idx = (*iterVec);
						SItem newitem;
						newitem.nItemID = item.nItemID;
						newitem.byBind = item.byBind;
						newitem.nNum = nNumEx;
						//
						mapIndexItem[idx] = newitem;
						vecEmptyGrid.erase(iterVec);
					}
				} // end of if (nLeft > 0)
			} // if (nLeft > 0)
		} //end of for (; iterInItem != lstInItemEx.end(); ++iterInItem)

	} // end of for (; iterLabel != mapInLabelItem.end(); ++iterLabel)
	
	//标签页不可堆叠物品处理
	MAP_LABEL_VEC_ITEM_PROTO_EX::iterator iterNoPile = mapInLabelVecItemProtoEx.begin();
	for (; iterNoPile != mapInLabelVecItemProtoEx.end(); ++iterNoPile)
	{
		int8_t byLabel = iterNoPile->first;
		VEC_ITEM_PROTO_EX &vecNoPileProtoEx = iterNoPile->second;
		//标签页剩余格子数
		VEC_UINT16 *pLabelNewGrid = nullptr;
		if (EPackageType_packge == byPackageType)
		{
			MAP_INT8_VEC_UINT16::iterator iterLabelGrid = mapLabelVecGrid.find(byLabel);
			if (iterLabelGrid == mapLabelVecGrid.end())
			{
				VEC_UINT16 vecNewGrid;
				vecNewGrid.clear();
				GetEmptyGrid(byLabel, vecNewGrid);
				mapLabelVecGrid[byLabel] = vecNewGrid;
				pLabelNewGrid = &mapLabelVecGrid[byLabel];
			}
			else
			{
				pLabelNewGrid = &iterLabelGrid->second;
			}
		}
		else
		{
			pLabelNewGrid = &vecStorgeNewGrid;
		}


		//
		VEC_UINT16 &vecEmptyGrid = *pLabelNewGrid;
		if (vecEmptyGrid.size() < vecNoPileProtoEx.size())
		{
			return false; //格子不够
		}
		VEC_ITEM_PROTO_EX::iterator iterNewProto = vecNoPileProtoEx.begin();
		for (; iterNewProto != vecNoPileProtoEx.end(); ++iterNewProto)
		{
			ItemProtoInfo &proto = (*iterNewProto);
			VEC_UINT16::iterator iter = vecEmptyGrid.begin();
			uint16_t idx = (*iter);
			vecEmptyGrid.erase(iter);
			mapOutNewIdxItemProtoEx[idx] = proto;

		}
	}


	if (mapIndexItem.size() > 0)
	{
		VEC_UINT16 vecNewItemGrid;
		vecNewItemGrid.clear();
		LIST_ITEM lstNewItem;
		lstNewItem.clear();
		MAP_INDEX_ITEM::iterator iterNew = mapIndexItem.begin();
		for (; iterNew != mapIndexItem.end(); ++iterNew)
		{
			vecNewItemGrid.push_back(iterNew->first);
			lstNewItem.push_back(iterNew->second);
		}
		VEC_ITEM_PROTO_EX vecNewProtoEx;
		vecNewProtoEx.clear();
		SItemCond itemCond;
		g_GetDropMgr()->GetItemCond(dynamic_cast<Player*>(m_pMaster),itemCond);
		if (!g_GetItemMgr()->CreateItem(lstNewItem, vecNewProtoEx, itemCond, false))
		{
			return false;
		}
		if (vecNewProtoEx.size() > vecNewItemGrid.size())
		{
			return false;
		}
		//设置索引
		VEC_ITEM_PROTO_EX::iterator iterProto = vecNewProtoEx.begin();
		for (; iterProto != vecNewProtoEx.end(); ++iterProto)
		{
			ItemProtoInfo &proto = (*iterProto);
			VEC_UINT16::iterator iter = vecNewItemGrid.begin();
			uint16_t idx = (*iter);
			mapOutNewIdxItemProtoEx[idx] = proto;
			vecNewItemGrid.erase(iter);
		}
	}
	
	return true;
}
//添加背包物品
bool PackagePart::AddPackageItem(MAP_UINT16_INT32 &mapOutGridAddNum, MAP_INDEX_ITEM_PROTO_EX &mapOutNewIdxItemProtoEx, bool update /*= true*/)
{
	return AddPackageItem(mapOutGridAddNum, mapOutNewIdxItemProtoEx, EPackageType_packge, update);
}
//添加仓库物品
bool PackagePart::AddStorageItem(MAP_UINT16_INT32 &mapOutGridAddNum, MAP_INDEX_ITEM_PROTO_EX &mapOutNewIdxItemProtoEx, bool update /*= true*/)
{
	return AddPackageItem(mapOutGridAddNum, mapOutNewIdxItemProtoEx, EPackageType_storage, update);
}
//添加背包物品
bool PackagePart::AddPackageItem(MAP_UINT16_INT32 &mapOutGridAddNum, MAP_INDEX_ITEM_PROTO_EX &mapOutNewIdxItemProtoEx,int8_t byPackageType, bool update)
{
	if (!ValidPackageType(byPackageType))
	{
		return false;
	}
	PackageUpdateRet protoUpdateRet;
	StorageUpdateRsp protoStorageUpdateRet;
	if (mapOutNewIdxItemProtoEx.size() > 0)
	{
		VEC_ITEM_PROTO_EX vecItemProEx;
		vecItemProEx.clear();
		MAP_INDEX_ITEM_PROTO_EX::iterator iterProto = mapOutNewIdxItemProtoEx.begin();
		for (; iterProto != mapOutNewIdxItemProtoEx.end(); ++iterProto)
		{
			uint16_t idx = iterProto->first;
			ItemProtoInfo &proto = iterProto->second;
			proto.set_index(idx);
			vecItemProEx.push_back(proto);
		}

		VEC_PACKAGE_ITEM vecItems;
		vecItems.clear();
		if (!g_GetItemMgr()->CreateItem(vecItemProEx, vecItems))
		{
			return false;
		}
		VEC_PACKAGE_ITEM::iterator iterItem = vecItems.begin();
		while (iterItem != vecItems.end())
		{
			CItemBase *pItem = (*iterItem);
			if (nullptr != pItem)
			{
				uint16_t idx = pItem->GetIndex();
				if (!ValidIndexByPackageType(idx,byPackageType))
				{
					continue;
				}
				if (nullptr == GetItemByPackageType(byPackageType,idx))
				{
					if (idx == SetItemByPackageType(byPackageType,idx,pItem))
					{
						iterItem = vecItems.erase(iterItem);
						if (EPackageType_packge == byPackageType)
						{
							m_setIdxRecord.insert(idx);
							AddPackageUpdateInfo(pItem, protoUpdateRet);
						}
						else
						{
							AddStorageUpdateInfo(pItem, protoStorageUpdateRet);
						}
						continue;
					}
					else
					{
						LogErrFmtPrint("[logic] PackagePart::AddPackageItem... SetItemByPackageType failed...idx:%d,itemid:%u ", idx, pItem->GetItemID());
					}
				}
				else
				{
					LogErrFmtPrint("[logic] PackagePart::AddPackageItem...GetItemByPackageType index is not nullptr...idx:%d， byPackageType:%d ", idx,byPackageType);
				}			
			} // end of if (nullptr != pItem)

			++iterItem;
		}
		
		//回收失败的物品
		VEC_PACKAGE_ITEM::iterator iterDel = vecItems.begin();
		for (; iterDel != vecItems.end(); ++iterDel)
		{
			CItemBase *pDelItem = (*iterDel);
			g_GetItemMgr()->FreeItemObj(pDelItem);
		}
	}

	MAP_UINT16_INT32::iterator iterGrid = mapOutGridAddNum.begin();
	for (; iterGrid != mapOutGridAddNum.end(); ++iterGrid)
	{
		uint16_t idx = iterGrid->first;
		int32_t addNum = iterGrid->second;
		CItemBase *pItem = GetItemByPackageType(byPackageType, idx);
		if (nullptr == pItem)
		{
			LogErrFmtPrint("[logic] PackagePart::AddPackageItem...GetItemByPackageType is nullptr ....idx:%d, byPackageType:%d ", byPackageType);
			continue;
		}
		pItem->AddNum(addNum);
		if (EPackageType_packge == byPackageType)
		{
			m_setIdxRecord.insert(idx);
			AddPackageUpdateInfo(pItem, protoUpdateRet);
		}
		else
		{
			AddStorageUpdateInfo(pItem, protoStorageUpdateRet);
		}
	}

	if (update)
	{
		if (EPackageType_packge == byPackageType)
		{
			//更新背包
			UpdatePackageInfo(protoUpdateRet);
		}
		else
		{
			StorageUpdate(protoStorageUpdateRet);
		}
	}	


	return true;
}

//添加物品事件处理
void PackagePart::OnAddItemEvent(MAP_UINT16_INT32 &mapOutGridAddNum, MAP_INDEX_ITEM_PROTO_EX &mapOutNewIdxItemProtoEx, SItemSourceParam &sourceParam)
{
	//增加物品，触发事件
	MAP_UINT32_INT32 mapCollectItems;
	mapCollectItems.clear();
	MAP_UINT16_INT32::iterator iterAdd = mapOutGridAddNum.begin();
	for (; iterAdd != mapOutGridAddNum.end(); ++iterAdd)
	{
		CItemBase *pItem = GetItemByIndex(iterAdd->first);
		if (nullptr != pItem)
		{
			AddCollectItem(pItem->GetItemID(), iterAdd->second, mapCollectItems);
		}
	}
	MAP_INDEX_ITEM_PROTO_EX::iterator iterProto = mapOutNewIdxItemProtoEx.begin();
	for (; iterProto != mapOutNewIdxItemProtoEx.end(); ++iterProto)
	{
		ItemProtoInfo &proto = iterProto->second;
		AddCollectItem(proto.item_id(), proto.item_num(), mapCollectItems);
	}

	CollectItemEvent(mapCollectItems, sourceParam, EItemOpetateType_Add);
}

//填充传出参数
void PackagePart::OnAddItemParam(MAP_UINT16_INT32 &mapOutGridAddNum, MAP_INDEX_ITEM_PROTO_EX &mapOutNewIdxItemProtoEx, VEC_ITEM_PROTO_EX &vecProtoExParam)
{
	MAP_UINT16_INT32::iterator iterGrid = mapOutGridAddNum.begin();
	for (; iterGrid != mapOutGridAddNum.end(); ++iterGrid)
	{
		uint16_t idx = iterGrid->first;
		int32_t num = iterGrid->second;
		CItemBase *pItem = GetItemByIndex(idx);
		if (nullptr != pItem)
		{
			ItemProtoInfo proto;
			if (g_GetItemMgr()->SetItemProtoInfo(pItem, &proto, num))
			{
				vecProtoExParam.push_back(proto);
			}
		}
	}
	MAP_INDEX_ITEM_PROTO_EX::iterator iterProto = mapOutNewIdxItemProtoEx.begin();
	for (; iterProto != mapOutNewIdxItemProtoEx.end(); ++iterProto)
	{
		uint16_t idx = iterProto->first;
		ItemProtoInfo &proto = iterProto->second;
		//
		ItemProtoInfo protoParam(proto);
		protoParam.set_index(idx);
		vecProtoExParam.push_back(protoParam);
	}
}

//包裹整理
bool PackagePart::BagItemSort(int8_t byPackageType)
{
	if (!ValidPackageType(byPackageType))
	{
		return false;
	}
	CompareFunc *pEquipCompareFunc = g_GetItemMgr()->GetCompareFunc(EPackageLabel_equip);
	CompareFunc *pMaterialCompareFunc = g_GetItemMgr()->GetCompareFunc(EPackageLabel_material);
	CompareFunc *pSundryCompareFunc = g_GetItemMgr()->GetCompareFunc(EPackageLabel_sundry);
	if (nullptr == pEquipCompareFunc || nullptr == pMaterialCompareFunc || nullptr == pSundryCompareFunc)
	{
		return false;
	}
	CharIDType cid = m_pMaster->GetCid();
	//装备>材料>杂物
	VEC_PACKAGE_ITEM vecMaterial;
	vecMaterial.clear();
	VEC_PACKAGE_ITEM vecSundry;
	vecSundry.clear();
	VEC_ITEM_PROTO_EX vecEquipProtoEx;
	vecEquipProtoEx.clear();

	uint16_t startIdx = GetLabelStartIdxByPackageType(EPackageLabel_all,byPackageType);
	uint16_t endIdx = GetLabelEndIdxByPackageType(EPackageLabel_all,byPackageType);
	if (!ValidLabelIndexByPackageType(EPackageLabel_all,startIdx,byPackageType) || !ValidLabelIndexByPackageType(EPackageLabel_all,endIdx,byPackageType))
	{
		LogErrFmtPrint("[logic] PackagePart::BagItemSort...ValidLabelIndexByPackageType...byPackageType:%d, startIdx:%d, endIdx:%d ",byPackageType,startIdx,endIdx);
		return false;
	}
	/*if (EPackageType_packge == byPackageType)
	{
		startIdx = GetLabelStartIdx(EPackageLabel_all);
		endIdx = GetLabelEndIdx(EPackageLabel_all);
	}
	else
	{ 
		startIdx = GetStorageStartIdx();
		endIdx = GetStorageEndIdx();
	}*/

	for (uint16_t i = startIdx; i <= endIdx; ++i)
	{
		CItemBase *pItem = GetItemByPackageType(byPackageType,i);
		if (nullptr == pItem)
		{
			continue;
		}
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pItem->GetItemID());
		if (nullptr != pEquipCfg)
		{
			//装备
			ItemProtoInfo equipProto;
			if (g_GetItemMgr()->SetItemProtoInfo(pItem, &equipProto))
			{
				vecEquipProtoEx.push_back(equipProto);
			}
		}
		else
		{
			const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItem->GetItemID());
			if (nullptr != pItemCfg && EPackageLabel_material == pItemCfg->itemType)
			{
				//材料
				vecMaterial.push_back(pItem);
			}
			else if (nullptr != pItemCfg && (int32_t)EItemFuncType::EItemFuncType_Fashion == pItemCfg->functionType)
			{
				//时装解锁类物品，需要跟装备一起排序，所以，这里加到装备vector中
				ItemProtoInfo proto;
				if (g_GetItemMgr()->SetItemProtoInfo(pItem, &proto))
				{
					vecEquipProtoEx.push_back(proto);
				}
			}
			else
			{
				//杂物
				vecSundry.push_back(pItem);
			}
		}
	}
	
	//装备索引 
	VEC_PACKAGE_ITEM vecEquipItems;
	vecEquipItems.clear();
	bool retC = g_GetItemMgr()->CreateItem(vecEquipProtoEx, vecEquipItems);
	
	//材料
	VEC_PACKAGE_ITEM vecMaterialItems;
	vecMaterialItems.clear();
	VEC_ITEM_PROTO_EX vecMaterialProto;
	vecMaterialProto.clear();
	//堆叠合并
	PileMerge(vecMaterial, vecMaterialProto);
	bool retA = g_GetItemMgr()->CreateItem(vecMaterialProto, vecMaterialItems);

	//杂物
	VEC_PACKAGE_ITEM vecSundryItems;
	vecSundryItems.clear();
	VEC_ITEM_PROTO_EX vecSundryProtoEx;
	vecSundryProtoEx.clear();
	//堆叠合并
	PileMerge(vecSundry, vecSundryProtoEx);
	bool retB = g_GetItemMgr()->CreateItem(vecSundryProtoEx, vecSundryItems);

	//判断创建物品的结果
	if (!retA || !retB || !retC) //创建物品失败，需要回收物品
	{
		VEC_PACKAGE_ITEM::iterator iterDelA = vecMaterialItems.begin();
		for (; iterDelA != vecMaterialItems.end(); ++iterDelA)
		{
			CItemBase *pDelItem = (*iterDelA);
			g_GetItemMgr()->FreeItemObj(pDelItem);
		}

		VEC_PACKAGE_ITEM::iterator iterDelB = vecSundryItems.begin();
		for (; iterDelB != vecSundryItems.end(); ++iterDelB)
		{
			CItemBase *pDelItem = (*iterDelB);
			g_GetItemMgr()->FreeItemObj(pDelItem);
		}

		VEC_PACKAGE_ITEM::iterator iterDelC = vecEquipItems.begin();
		for (; iterDelC != vecEquipItems.end(); ++iterDelC)
		{
			CItemBase *pDelItem = (*iterDelC);
			g_GetItemMgr()->FreeItemObj(pDelItem);
		}

		LogErrFmtPrint("[logic] PackagePart::BagItemSort....!retA || !retB.....cid:%lu, byPackageType:%d ", cid, byPackageType);

		return false;
	}

	//先清空包裹内所有的格子，然后按装备，材料，杂物的顺序设置物品
	for (uint16_t j = startIdx; j <= endIdx; ++j)
	{
		CItemBase *pItem = GetItemByPackageType(byPackageType,j);
		if (nullptr == pItem)
		{
			continue;
		}
		//先设置格子为空，然后回收物品
		uint16_t idx = pItem->GetIndex();
		SetItemByPackageType(byPackageType, idx, nullptr);
		//回收物品
		g_GetItemMgr()->FreeItemObj(pItem);
	}

	//排序
	std::sort(std::begin(vecEquipItems), std::end(vecEquipItems), *pEquipCompareFunc);
	std::sort(std::begin(vecMaterialItems), std::end(vecMaterialItems), *pMaterialCompareFunc);
	std::sort(std::begin(vecSundryItems), std::end(vecSundryItems), *pSundryCompareFunc);
	

	//需要回收的物品
	VEC_PACKAGE_ITEM vecDelItem;
	vecDelItem.clear();
	//设置 装备，材料，杂物
	uint16_t idxEquip = startIdx; //从开始索引开始
	VEC_PACKAGE_ITEM::iterator iterEquip = vecEquipItems.begin();
	for (; iterEquip != vecEquipItems.end(); ++iterEquip)
	{
		CItemBase *pItem = (*iterEquip);
		if (nullptr != pItem)
		{
			pItem->SetIndex(idxEquip);
			if (idxEquip != SetItemByPackageType(byPackageType,idxEquip,pItem))
			{
				//失败，需要回收
				MMOLOG_FMT_ERROR("[logic] PackagePart::BagItemSort....equip SetItemByPackageType failed..cid:%lu, idx:%d, byPackageType:%d ", cid, idxEquip, byPackageType);
				vecDelItem.push_back(pItem);
			}
			else
			{
				++idxEquip;
			}			
		}
	}

	//材料
	uint16_t idxMaterial = idxEquip;//materialStartIdx;
	VEC_PACKAGE_ITEM::iterator iterMt = vecMaterialItems.begin();
	for (; iterMt != vecMaterialItems.end(); ++iterMt)
	{
		CItemBase *pItem = (*iterMt);
		if (nullptr != pItem)
		{
			pItem->SetIndex(idxMaterial);
			if (idxMaterial != SetItemByPackageType(byPackageType,idxMaterial, pItem))
			{
				//失败，需要回收
				MMOLOG_FMT_ERROR("[logic] PackagePart::BagItemSort....material SetItemByPackageType failed..cid:%lu, idx:%d, byPackageType:%d ", cid, idxMaterial, byPackageType);
				vecDelItem.push_back(pItem);
			}
			else
			{
				++idxMaterial;
			}
		}
	}

	//杂物
	uint16_t idxSundry = idxMaterial;//sundryStartIdx;
	VEC_PACKAGE_ITEM::iterator iterSd = vecSundryItems.begin();
	for (; iterSd != vecSundryItems.end(); ++iterSd)
	{
		CItemBase *pItem = (*iterSd);
		if (nullptr != pItem)
		{
			pItem->SetIndex(idxSundry);
			if (idxSundry != SetItemByPackageType(byPackageType,idxSundry, pItem))
			{
				//失败，需要回收
				MMOLOG_FMT_ERROR("[logic] PackagePart::BagItemSort....sundry SetItemByIndex failed..cid:%lu, idx:%d, byPackageType:%d ", cid, idxSundry, byPackageType);
				vecDelItem.push_back(pItem);
			}
			else
			{
				++idxSundry;
			}
		}
	}

	//需要回收的物品
	VEC_PACKAGE_ITEM::iterator iterDel = vecDelItem.begin();
	for (; iterDel != vecDelItem.end(); ++iterDel)
	{
		CItemBase *pDelItem = (*iterDel);
		g_GetItemMgr()->FreeItemObj(pDelItem);
	}

	return true;
}

//堆叠合并
uint16_t PackagePart::PileMerge(VEC_PACKAGE_ITEM vecItems,VEC_ITEM_PROTO_EX &vecPileProtoEx)
{
	VEC_ITEM_PROTO_EX vecSrcItems;
	MAP_ITEM_PROTO_EX mapDstItems;
	vecSrcItems.clear();
	mapDstItems.clear();
	uint16_t startIdx = 1;
	//
	VEC_PACKAGE_ITEM::iterator iterItem = vecItems.begin();
	for (; iterItem != vecItems.end(); ++iterItem)
	{
		CItemBase *pItem = (*iterItem);
		if (nullptr == pItem)
		{
			continue;
		}
		ItemProtoInfo proto;
		if (g_GetItemMgr()->SetItemProtoInfo(pItem, &proto))
		{
			vecSrcItems.push_back(proto);
		}
	}


	//按标签格子顺序合并堆叠数
	uint16_t nNewIdx = startIdx;
	VEC_ITEM_PROTO_EX::iterator iterSrc = vecSrcItems.begin();
	while (iterSrc != vecSrcItems.end())
	{
		ItemProtoInfo &srcProto = (*iterSrc);
		if (srcProto.item_num() <= 0)
		{
			++iterSrc;
			continue;
		}
		const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(srcProto.item_id());
		if (nullptr == pItemCfg)
		{
			LogErrFmtPrint("[logic] PackagePart::PileMerge ...nullptr == pItemCfg ..itemid:%u ", srcProto.item_id());
			++iterSrc;
			continue;
		}
		int32_t stackLimit = g_GetItemMgr()->ItemMaxPile(pItemCfg);
		if (mapDstItems.size() == 0 || stackLimit <= 1)
		{
			srcProto.set_index(nNewIdx);
			mapDstItems[nNewIdx++] = srcProto;
			++iterSrc;
			continue;
		}

		MAP_ITEM_PROTO_EX::iterator iterDst = mapDstItems.begin();
		for (; iterDst != mapDstItems.end(); ++iterDst)
		{
			ItemProtoInfo &dstProto = iterDst->second;
			int32_t dstNum = dstProto.item_num();
			uint32_t dstItemID = dstProto.item_id();


			if (dstNum < stackLimit
				&& dstItemID == srcProto.item_id()
				&& dstProto.bind() == srcProto.bind()
				)
			{
				uint16_t nLeftPileNum = stackLimit - dstNum;
				int32_t nPileNum = srcProto.item_num();
				if (nLeftPileNum >= nPileNum)
				{

					dstNum += nPileNum;
					nPileNum -= nPileNum;
				}
				else
				{
					dstNum += nLeftPileNum;
					nPileNum -= nLeftPileNum;
				}

				dstProto.set_item_num(dstNum);
				srcProto.set_item_num(nPileNum);
			}
			if (srcProto.item_num() == 0)
			{
				//格子已经为空了
				break;
			}
		} // end of for (; iterDst != mapDstItems.end(); ++iterDst)

		if (srcProto.item_num() > 0)
		{
			ItemProtoInfo newProto(srcProto);
			newProto.set_index(nNewIdx);
			mapDstItems[nNewIdx++] = newProto;
		}

		++iterSrc;
	}

	MAP_ITEM_PROTO_EX::iterator iterPile = mapDstItems.begin();
	for (; iterPile != mapDstItems.end(); ++iterPile)
	{
		//uint16_t idx = iterPile->first;
		ItemProtoInfo &proto = iterPile->second;
		vecPileProtoEx.push_back(proto);
	}
	
	//返回最后一个索引，nNewIdx
	return (nNewIdx - 1);
}

//添加背包更新信息
bool PackagePart::AddPackageUpdateInfo(CItemBase *pItem, PackageUpdateRet &ret, bool bDel /*= false*/)
{
	if (nullptr == pItem)
	{
		return false;
	}
	ItemProtoInfo *protoItemInfo = ret.add_item_list();
	if (nullptr != protoItemInfo)
	{
		SetUpdateItemInfo(pItem, protoItemInfo, bDel);
	}
	return true;
}
//设置更新信息
bool PackagePart::SetUpdateItemInfo(CItemBase *pItem, ItemProtoInfo *protoItemInfo, bool bDel /*= false*/)
{
	if (bDel)
	{
		return g_GetItemMgr()->SetItemProtoInfo(pItem, protoItemInfo, 0);
	}
	return g_GetItemMgr()->SetItemProtoInfo(pItem, protoItemInfo);
	
}

//设置槽位信息
void PackagePart::SetEquipSlotInfo(EquipSlot &slot, EquipSlotProto *protoSlot)
{
	protoSlot->set_index(slot.m_nIndex);
	protoSlot->set_strenlv(slot.m_nStrenLev);
}

//添加装备穿在身上
bool PackagePart::AddEquipOnBody(uint32_t equipConfigID)
{
	if (0 == equipConfigID)
	{
		return false;
	}
	
	const EquipEquipCfgInfo *pSEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(equipConfigID);
	if (nullptr != pSEquipCfg)
	{
		int32_t equipPos = pSEquipCfg->position;

		if (pSEquipCfg->position == EEquipPos_ring )
		{
			if (!GetEquip(pSEquipCfg->position))
			{
				equipPos =  EEquipPos_ring_ex;
			}
		}
		else if (pSEquipCfg->position == EEquipPos_ring_ex)
		{
			if (!GetEquip(pSEquipCfg->position))
			{
				equipPos =  EEquipPos_ring;
			}
		}
		else if (pSEquipCfg->position == EEquipPos_bracer)
		{
			if (!GetEquip(pSEquipCfg->position))
			{
				equipPos =  EEquipPos_bracer_ex;
			}
		}
		else if (pSEquipCfg->position == EEquipPos_bracer_ex)
		{
			if (!GetEquip(pSEquipCfg->position))
			{
				equipPos =  EEquipPos_bracer;
			}
		}

		if (nullptr == GetEquip(equipPos))
		{
			CItemBase *pNewEquip = g_GetItemMgr()->MakeItemObj(EItemType_equip);
			if (nullptr != pNewEquip)
			{
				SItemCond itemCond;
				g_GetDropMgr()->GetItemCond(dynamic_cast<Player*>(m_pMaster), itemCond);
				if (pNewEquip->Init(equipPos, equipConfigID, itemCond, 1, (int8_t)pSEquipCfg->bindType))
				{
					if (equipPos == (uint8_t)SetEquipByIndex(equipPos, (CEquip*)pNewEquip))
					{
						return true;
					}
				}
				g_GetItemMgr()->FreeItemObj(pNewEquip);
			}
		}
	}
	return false;
}
//添加收集物品（主要是用于任务收集物品）
void PackagePart::AddCollectItem(uint32_t nItemID, int32_t nNum, MAP_UINT32_INT32 &mapCollectItems)
{
	MAP_UINT32_INT32::iterator iter = mapCollectItems.find(nItemID);
	if (iter != mapCollectItems.end())
	{
		iter->second += nNum;
	}
	else
	{
		mapCollectItems[nItemID] = nNum;
	}
}
//收集物品事件触发
void PackagePart::CollectItemEvent(MAP_UINT32_INT32 &mapCollectItems, SItemSourceParam &sourceParam, int32_t nOperateType)
{
	if (mapCollectItems.size() == 0)
	{
		return;
	}
	MissionPart *pPart = static_cast<MissionPart*>(m_pMaster->GetPart(PART_MISSION));
	if (nullptr != pPart)
	{
		MAP_UINT32_INT32::iterator iter = mapCollectItems.begin();
		for (; iter != mapCollectItems.end(); ++iter)
		{
			ItemChangeEvent itemChangeEvent;
			itemChangeEvent.itemId = iter->first;
			itemChangeEvent.itemNum = iter->second;
			itemChangeEvent.changeType = sourceParam.source;
			itemChangeEvent.opetateType = nOperateType;
			itemChangeEvent.itemSource = sourceParam;
			g_GetEvent()->FireExecute(EVENT_ITEM_CHANGE, m_pMaster->GetCid(), CREATURE_PLAYER, &itemChangeEvent, sizeof(ItemChangeEvent));
		}
	}
}
//第一次登陆
void PackagePart::FirstLogin()
{
	uint8_t byprof = (uint8_t)m_pMaster->GetAttr(C_PROF);
	uint8_t bysex = (uint8_t)m_pMaster->GetAttr(C_GENDER);
	const RoleBornCfgInfo *pRoleBornCfg = g_GetRoleBornCfg(byprof, bysex);
	if (nullptr != pRoleBornCfg)
	{
		LIST_ITEM lstBornItem;
		lstBornItem.clear();
		VecRoleBornItemCfg::const_iterator iterVec = pRoleBornCfg->vecRoleBornItemCfg.begin();
		for (; iterVec != pRoleBornCfg->vecRoleBornItemCfg.end(); ++iterVec)
		{
			const RoleBornItemCfgInfo &bornItem = (*iterVec);
			if (bornItem.name <= 0 || bornItem.num <= 0)
			{
				continue;
			}
			const EquipEquipCfgInfo *pEquipCfg = nullptr;
			const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(bornItem.name);
			if (nullptr != pItemCfg)
			{
				SItem sitem;
				sitem.nItemID = bornItem.name;
				sitem.nNum = bornItem.num;
				lstBornItem.push_back(sitem);
			}
			else
			{
				pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(bornItem.name);
				if (nullptr != pEquipCfg)
				{
					SItem sitem;
					sitem.nItemID = bornItem.name;
					sitem.nNum = 1; //装备数量只能是1
					lstBornItem.push_back(sitem);
				}
				else
				{
					LogErrFmtPrint("[logic] PackagePart::FirstLogin....can not find item cfg...itemid:%d, num:%d ", bornItem.name, bornItem.num);
				}
			}

		}
		//这里直接添加物品 ,第一次登陆添加的物品不要更新到前端
		SItemSourceParam sourceParam;
		sourceParam.source = S_Born;
		AddItem(lstBornItem, sourceParam, false);
	}
	else
	{
		LogErrFmtPrint("[logic] PackagePart::FirstLogin nullptr == pRoleBornCfg....byprof:%u , bysex:%u ", byprof,bysex);
	}
}

////////////////////////////////  仓库接口 //////////////////////////////////////////
//是否是有效的索引
bool PackagePart::ValidStorageIndex(uint16_t nIndex)
{
	if (nIndex >= 1 && nIndex < s_totalStorageGrid)
	{
		return true;
	}
	return false;
}
//设置物品
uint16_t PackagePart::SetStorageItemByIndex(uint16_t nIndex, CItemBase *pItem)
{
	if (!ValidStorageIndex(nIndex))
	{
		return 0;
	}
	m_vecStorage[nIndex] = pItem;
	return nIndex;
}
//通过索引获取物品
CItemBase *PackagePart::GetStorageItemByIndex(int16_t nIndex)
{
	if (ValidStorageIndex(nIndex))
	{
		return m_vecStorage[nIndex];
	}
	return nullptr;
}
//获取仓库开始索引
uint16_t PackagePart::GetStorageStartIdx()
{
	return 1;
}
//获取仓库结束索引
uint16_t PackagePart::GetStorageEndIdx()
{
	return (m_storageExpand + STORAGE_INIT_GRID_NUM);
}


//获取仓库空格子索引列表
bool PackagePart::GetStorageEmptyGrid(VEC_UINT16 &vecGrid, uint16_t nNum/* = 0*/)
{
	vecGrid.clear();
	//
	uint16_t startIdx = GetStorageStartIdx();
	uint16_t nEndIndex = GetStorageEndIdx();
	for (size_t i = startIdx; i <= nEndIndex; ++i)
	{
		if (nullptr == GetStorageItemByIndex(i))
		{
			vecGrid.push_back(i);
		}
		if (nNum > 0 && vecGrid.size() >= (size_t)nNum)
		{
			break;
		}
	}

	if (nNum > 0)
	{
		if (vecGrid.size() >= (size_t)nNum)
		{
			return true;
		}
		vecGrid.clear();
		return false;
	}
	
	return true;
}
//移除物品 index-num
bool PackagePart::RemoveStorageItem(MAP_UINT16_INT32 &mapIndexItem)
{
	ORDER_MAP_UINT16_INT32 mapIdxReduceNum;
	mapIdxReduceNum.clear();
	if (!HasStorageItem(mapIndexItem,mapIdxReduceNum))
	{
		return false;
	}
	MAP_UINT32_INT32 mapItemNum;
	mapItemNum.clear();
	RemoveSotrageItem(mapIdxReduceNum, mapItemNum);

	return true;
}
//添加仓库物品
bool PackagePart::AddStorageItem(VEC_ITEM_PROTO_EX &vecProtoEx)
{
	LIST_ITEM lstItem;
	lstItem.clear();
	MAP_LABEL_LIST_ITEM_EX mapOutLabelItem;
	MAP_LABEL_VEC_ITEM_PROTO_EX mapLabelVecProtoEx;
	MergeStorageItemList(lstItem, vecProtoEx, mapOutLabelItem, mapLabelVecProtoEx);

	MAP_UINT16_INT32 mapGridAddNum;
	MAP_INDEX_ITEM_PROTO_EX mapIndexProtoEx;
	if (!CanStorageAddItem(mapOutLabelItem, mapLabelVecProtoEx, mapGridAddNum, mapIndexProtoEx))
	{
		return false;
	}
	
	//前面已经判断过，直接增加
	AddStorageItem(mapGridAddNum, mapIndexProtoEx);

	return true;
}


//添加背包更新信息
bool PackagePart::AddStorageUpdateInfo(CItemBase *pItem, StorageUpdateRsp &ret, bool bDel /*= false*/)
{
	if (nullptr == pItem)
	{
		return false;
	}
	ItemProtoInfo *protoItemInfo = ret.add_item_list();
	if (nullptr != protoItemInfo)
	{
		SetUpdateItemInfo(pItem, protoItemInfo, bDel);
	}
	return true;
}


//仓库信息
void PackagePart::StorageInfo(const char *data, uint32_t len)
{
	StorageInfoRsp rsp;
	rsp.set_retcode(RET_SUCCESS);
	rsp.set_init_grid(STORAGE_INIT_GRID_NUM);
	rsp.set_expand_grid(m_storageExpand);
	uint16_t startIdx = GetStorageStartIdx();
	uint16_t endIdx = GetStorageEndIdx();
	for (uint16_t i = startIdx; i <= endIdx; ++i)
	{
		CItemBase *pItem = GetStorageItemByIndex(i);
		if (nullptr != pItem)
		{
			ItemProtoInfo *proto = rsp.add_item_list();
			if (nullptr != proto)
			{
				SetUpdateItemInfo(pItem, proto);
			}
		}
	}
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STORAGE_INFO, &rsp);
}
//仓库整理
void PackagePart::StorageSort(const char *data, uint32_t len)
{
	uint64_t curTime = g_GetGlobalServerTime()->UnixSec();
	if (curTime - m_lastStorageSort <= 3) //冷却
	{
		return;
	}
	StorageSortRsp rsp;
	rsp.set_retcode(RET_SUCCESS);
	if (!BagItemSort(EPackageType_storage))
	{
		rsp.set_retcode(RET_FAIL);
	}
	else
	{
		//整理完了之后，把所有的物品在此发给客户端
		m_lastStorageSort = g_GetGlobalServerTime()->UnixSec();
		//
		uint16_t startIdx = GetStorageStartIdx();
		uint16_t endIdx = GetStorageEndIdx();
		for (uint16_t j = startIdx; j <= endIdx; ++j)
		{
			CItemBase *pItem = GetStorageItemByIndex(j);
			if (nullptr != pItem)
			{
				ItemProtoInfo *proto = rsp.add_item_list();
				if (nullptr != proto)
				{
					SetUpdateItemInfo(pItem, proto);
				}
			}
		}
	}

	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STORAGE_SORT, &rsp);
}

//仓库操作（移入，移出）
void PackagePart::StorageOperate(const char *data, uint32_t len)
{
	StorageOperateReq req;
	if (!req.ParseFromArray(data,len))
	{
		LogErrFmtPrint("[logic] PackagePart::StorageOperate...StorageOperateReq parse failed...");
		return;
	}
	//操作类型，1 从背包移动物到仓库，2 从仓库移动物品到背包
	int32_t type = req.operate_type();
	//操作索引 从背包移到仓库时代表 背包索引，  从仓库移动到背包 代表仓库索引
	int32_t idx = req.operate_index();
	int32_t num = req.operate_num(); //为0 表示整个格子物品
	if (1 != type && 2 != type)
	{
		return;
	}
	if (num < 0)
	{
		return;
	}

	StorageOperateRsp rsp;
	CItemBase *pIdxItem = nullptr;
	if (1 == type)
	{
		pIdxItem = GetItemByIndex(idx);
	}
	else
	{
		pIdxItem = GetStorageItemByIndex(idx);
	}
	if (nullptr == pIdxItem)
	{
		//物品不存在
		rsp.set_retcode(RET_PACKAGE_ITEM_NOT_EXITS);
	}
	else if (num > (int32_t)pIdxItem->GetNum())
	{
		//物品数量不足
		rsp.set_retcode(RET_PACKAGE_ITEM_NUM_LACK);
	}
	else
	{
		int32_t nNum = num;
		if (0 == num)
		{
			nNum = pIdxItem->GetNum();
		}
		//
		ItemProtoInfo protoItem;
		if (!SetUpdateItemInfo(pIdxItem,&protoItem))
		{
			LogErrFmtPrint("[logic] PackagePart::StorageOperate...SetUpdateItemInfo failed...");
			return;
		}
		//设置数量
		protoItem.set_item_num(nNum);
		//
		MAP_UINT16_INT32 mapIdxNum;
		mapIdxNum[pIdxItem->GetIndex()] = nNum;
		//
		VEC_ITEM_PROTO_EX vecProtoEx;
		vecProtoEx.push_back(protoItem);
		if (1 == type) //从背包移动物到仓库
		{
			
			if (AddStorageItem(vecProtoEx))
			{
				SItemSourceParam sourceParam;
				sourceParam.source = S_Storage;
				RemoveItem(mapIdxNum, sourceParam); //从背包移除
				rsp.set_retcode(RET_SUCCESS);
			}
			else
			{
				//仓库空间不够
				rsp.set_retcode(RET_PACKAGE_STORAGE_SPACE_NOT_ENOUGH);
			}
		}
		else  //从仓库移动到背包
		{
			SItemSourceParam sourceParam;
			sourceParam.source = S_Storage;
			if (AddItem(vecProtoEx, sourceParam))
			{
				RemoveStorageItem(mapIdxNum);
				rsp.set_retcode(RET_SUCCESS);
			}
			else
			{
				//背包空间不足
				rsp.set_retcode(RET_PACKAGE_SPACE_NOT_ENOUGH);
			}
		}
	}

	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STORAGE_OPERATE, &rsp);
}

//仓库更新
void PackagePart::StorageUpdate(StorageUpdateRsp &ret)
{
	if (ret.item_list_size() > 0)
	{
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STORAGE_UPDATE, &ret);
	}
}



////////////////////////////////////////// 装备接口  //////////////////////////////////////////////
//是否是有效的装备位置
bool PackagePart::ValidEquipPos(uint8_t byPos)
{
	//if (byPos > EEquipPos_none && byPos < EEquipPos_limit)
	if (byPos > EEquipPos_none && byPos <= EEquipPos_talisman)
	{
		return true;
	}
	return false;
}
//是否是装备外观的位置
bool PackagePart::ValidEquipFacadePos(uint8_t byPos)
{
	if (byPos == EEquipPos_clothes
		|| byPos == EEquipPos_weapon
		|| byPos == EEquipPos_wing
		)
	{
		return true;
	}
	return false;
}

//获取装备
CEquip *PackagePart::GetEquip(uint8_t byPos, EEquipType eType)
{
	if (!ValidEquipPos(byPos))
	{
		return nullptr;
	}

	if (eType == EEquipType_Equip)
	{
		return m_vecPlayerEquip[byPos];
	}
	else if (eType == EEquipType_GodEquip)
	{
		return m_vecPlayerGodEquip[byPos];
	}
	return nullptr;
}

//计算装备属性
bool PackagePart::CalcEquipAttr(bool bSync /*= true*/)
{
	if (nullptr == m_pMaster)
	{
		return false;
	}
	Player *pPlayer = dynamic_cast<Player*>(m_pMaster);
	if (!pPlayer)
	{
		return false;
	}
	MAP_UINT32_VEC_UINT32 mapSuitVec;
	mapSuitVec.clear();
	MAP_UINT32_VEC_UINT32 mapGodSuitVec;
	mapGodSuitVec.clear();
	//uint32_t atrr[P_EQUIP_END] = { 0 };
	MAP_INT32_FLOAT mapAttr;
	mapAttr.clear();

	int32_t nPNumEquipBegin = g_GetAttrMgr()->GetEquipPNumStartIndex();
	int32_t nPNumEquipEnd = g_GetAttrMgr()->GetEquipPnumEndIndex();

	//LogDebugFmtPrint("[logic] +++++++++++++++++++++++++nPNumEquipBegin end+++++++++++++++++++%d,%d", nPNumEquipBegin, nPNumEquipEnd);

	for (int32_t n = nPNumEquipBegin; n < nPNumEquipEnd; ++n)
	{
		mapAttr[n] = 0.0f;
	}
	VEC_PLAYER_EQUIP::const_iterator iter = m_vecPlayerEquip.begin();
	for (; iter != m_vecPlayerEquip.end(); ++iter)
	{
		CEquip *pEquip = (*iter);
		if (nullptr == pEquip)
		{
			continue;
		}
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pEquip->GetItemID());
		if (nullptr == pEquipCfg)
		{
			LogErrFmtPrint("[logic] PackagePart::CalcEquipAttr...equip cfg not found ... itemid:%u ", pEquip->GetItemID());
			continue;
		}
		
		//装备槽
		EquipSlot &slot = m_vecEquipSlot[pEquip->GetIndex()];
		//精炼表
		const EquipRefineCfgInfo *pRefineCfg = g_GetEquipCfgMgr()->GetRefineCfgInfo(pEquipCfg->position, pEquip->GetRefineLev(), pEquipCfg->wearLevel);
		//强化表
		const EquipStrengthenCfgData *pStrenCfg = g_GetEquipCfgMgr()->GetStrenthCfgInfo(m_pMaster->GetAttr(C_PROF), pEquipCfg->position);
		if (nullptr == pStrenCfg)
		{
			LogErrFmtPrint("[logic] PackagePart::CalcEquipAttr...pStrenCfg cfg not found ... prof:%d, pos:%d ", m_pMaster->GetAttr(C_PROF), pEquipCfg->position);
			continue;
		}

		//基础属性
		MAP_INT32_INT32 *pBaseAttr = pEquip->GetBaseAttr();
		if (nullptr != pBaseAttr)
		{
			//精炼系数(精炼系数跟装备基础属性相关)
			float fRefineCoef = (pRefineCfg == nullptr) ? 0.f : pRefineCfg->refineProportion;
			MAP_INT32_INT32::const_iterator iterBase = pBaseAttr->begin();
			for (; iterBase != pBaseAttr->end(); ++iterBase)
			{
				if (iterBase->first > nPNumEquipBegin && iterBase->first < nPNumEquipEnd)
				{
					//强化属性，后面添加  强化每提升一级增加的属性=装备基础属性*精炼系数，取整显示
					mapAttr[iterBase->first] += (float)iterBase->second;
					mapAttr[iterBase->first] += (float)(iterBase->second * fRefineCoef);
				}
			}
		}
		
		//镶嵌宝石属性
		//VEC_UINT32 &inlayVec = slot.m_vecInaly;
		VEC_UINT32 *inlayVec = pEquip->GetInlay();
		for (VEC_UINT32::iterator iterInlay = inlayVec->begin(); iterInlay != inlayVec->end(); ++iterInlay)
		{
			uint32_t nStoneID = (*iterInlay);
			if (nStoneID == 0)		continue;
			const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(nStoneID);
			if (nullptr == pItemCfg)
			{
				LogErrFmtPrint("[logic] PackagePart::CalcEquipAttr...item cfg not found ... itemid:%u ", nStoneID);
				continue;
			}
			if (pItemCfg->subType < (int32_t)EItemSubType::EItemSubType_stone_begin || pItemCfg->subType >(int32_t)EItemSubType::EItemSubType_stone_end)
			{
				LogErrFmtPrint("[logic] PackagePart::CalcEquipAttr...item not stone type ... itemid:%u ,subtype:%d ", nStoneID, pItemCfg->subType);
				continue;
			}
			if ((int32_t)EItemFuncType::EItemFuncType_AttachAttr != pItemCfg->functionType)
			{
				continue;
			}
			VEC_INT32 vecParam;
			vecParam.clear();
			CommonApi::SplitStrToVecInt(pItemCfg->functionValue, ",", &vecParam);
			if (vecParam.size() != 2)		continue;
			uint32_t pattrID = g_GetAttrMgr()->GetPlayerFightModlePAttr(enFightAttrModule_Equip,vecParam.at(0));
			if (P_NONE != pattrID)
				mapAttr[pattrID] += (float)vecParam.at(1);
		}

		//精炼属性
		MAP_INT32_INT32 *pRefind = pEquip->GetRefineEx();
		if (nullptr != pRefind)
		{
			MAP_INT32_INT32::const_iterator iterRefine = pRefind->begin();
			for (; iterRefine != pRefind->end(); ++iterRefine)
				if (iterRefine->first > nPNumEquipBegin && iterRefine->first < nPNumEquipEnd)
					mapAttr[iterRefine->first] += (float)iterRefine->second;
		}

		//强化属性 公式：a*x^2+b*x+c       a，b，c为填写的系数，x为强化等级
		const VecEquipStrengthenStrengCfg &pVecStrenth = pStrenCfg->strenthCfg->vecEquipStrengthenStrengCfg;
		for (VecEquipStrengthenStrengCfg::const_iterator iter = pVecStrenth.begin(); iter != pVecStrenth.end(); ++iter)
		{
			int32_t pattrID = g_GetAttrMgr()->GetPlayerFightModlePAttr(enFightAttrModule_Equip,(*iter).type);
			if (pattrID > nPNumEquipBegin && pattrID < nPNumEquipEnd)
			{
				VEC_FLOAT vecParam;
				vecParam.clear();
				CommonApi::SplitStrToVecFloat((*iter).then, ",", &vecParam);
				if (vecParam.size() != 3)
				{
					LogErrFmtPrint("[logic] PackagePart::CalcEquipAttr...vecParam.size() != 3 ... prof:%d, pos: %d ", m_pMaster->GetAttr(C_PROF), pEquipCfg->position);
					continue;
				}
				mapAttr[pattrID] += vecParam[0] * slot.m_nStrenLev * slot.m_nStrenLev + vecParam[1] * slot.m_nStrenLev + vecParam[2];
			}
		 }

		//套装属性，后面添加
		if (pEquipCfg->suitId > 0)
		{
			MAP_UINT32_VEC_UINT32::iterator iterSuit = mapSuitVec.find(pEquipCfg->suitId);
			if (iterSuit != mapSuitVec.end())
			{
				VEC_UINT32 &vec = iterSuit->second;
				vec.push_back(pEquipCfg->id);
			}
			else
			{
				VEC_UINT32 vec;
				vec.push_back(pEquipCfg->id);
				mapSuitVec[pEquipCfg->suitId] = vec;
			}
		}
	}

	//神装
	VEC_PLAYER_EQUIP::const_iterator godIter = m_vecPlayerGodEquip.begin();
	for (; godIter != m_vecPlayerGodEquip.end(); ++godIter)
	{
		CEquip *pEquip = (*godIter);
		if (nullptr == pEquip)
		{
			continue;
		}
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pEquip->GetItemID());
		if (nullptr == pEquipCfg)
		{
			LogErrFmtPrint("[logic] PackagePart::CalcEquipAttr...equip cfg not found ... itemid:%u ", pEquip->GetItemID());
			continue;
		}

		//基础属性
		MAP_INT32_INT32 *pBaseAttr = pEquip->GetBaseAttr();
		if (nullptr != pBaseAttr)
		{
			//精炼系数(精炼系数跟装备基础属性相关)
			MAP_INT32_INT32::const_iterator iterBase = pBaseAttr->begin();
			for (; iterBase != pBaseAttr->end(); ++iterBase)
			{
				if (iterBase->first > nPNumEquipBegin && iterBase->first < nPNumEquipEnd)
				{
					//强化属性，后面添加  强化每提升一级增加的属性=装备基础属性*精炼系数，取整显示
					mapAttr[iterBase->first] += (float)iterBase->second;
				}
			}
		}

		//精炼属性
		MAP_INT32_INT32 *pRefind = pEquip->GetRefineEx();
		if (nullptr != pRefind)
		{
			MAP_INT32_INT32::const_iterator iterRefine = pRefind->begin();
			for (; iterRefine != pRefind->end(); ++iterRefine)
				if (iterRefine->first > nPNumEquipBegin && iterRefine->first < nPNumEquipEnd)
					mapAttr[iterRefine->first] += (float)iterRefine->second;
		}

		//套装属性，后面添加
		if (pEquipCfg->suitId > 0)
		{
			MAP_UINT32_VEC_UINT32::iterator iterSuit = mapGodSuitVec.find(pEquipCfg->suitId);
			if (iterSuit != mapGodSuitVec.end())
			{
				VEC_UINT32 &vec = iterSuit->second;
				vec.push_back(pEquipCfg->id);
			}
			else
			{
				VEC_UINT32 vec;
				vec.push_back(pEquipCfg->id);
				mapGodSuitVec[pEquipCfg->suitId] = vec;
			}
		}
	}

	//时装属性
	for (VEC_PLAYER_FASHION::iterator it = m_vecPlayerFashion.begin(); it != m_vecPlayerFashion.end(); it++)
	{
		if ((*it).isDress)
		{
			const EquipFashionCfgInfo *pFashionCfg = g_GetEquipFashionCfgTable()->GetEquipFashionCfgInfo((*it).fashionId);
			if (nullptr == pFashionCfg)
			{
				LogErrFmtPrint("[logic] PackagePart::CalcEquipAttr...pFashionCfg not found ... fashionId:%u ", (*it).fashionId);
			}
			else
			{
				VecEquipFashionAttributeCfg::const_iterator iterFashionAttr = pFashionCfg->vecEquipFashionAttributeCfg.begin();
				for (; iterFashionAttr != pFashionCfg->vecEquipFashionAttributeCfg.end(); ++iterFashionAttr)
				{
					int32_t nPAttr = g_GetAttrMgr()->GetPlayerFightModlePAttr(enFightAttrModule_Equip,(*iterFashionAttr).type);
					if (nPAttr > nPNumEquipBegin && nPAttr < nPNumEquipEnd)
						mapAttr[nPAttr] += (float)(*iterFashionAttr).value;
				}
			}
		}
	}

	//普通装备套装属性
	CalcSuitAttr(mapSuitVec, mapAttr, nPNumEquipBegin, nPNumEquipEnd);
	//神装套装属性
	CalcSuitAttr(mapGodSuitVec, mapAttr, nPNumEquipBegin, nPNumEquipEnd);

	string strLog = "";
	MAP_INT32_FLOAT::iterator iterAttrA = mapAttr.begin();
	for (; iterAttrA != mapAttr.end(); ++iterAttrA)
	{
		int32_t pattrId = iterAttrA->first;
		if (pattrId > nPNumEquipBegin && pattrId < nPNumEquipEnd)
		{
			int32_t attrVal = (int32_t)floor(iterAttrA->second);	//最后向下取整
			if (attrVal > 0)
			{
				char szTmp[50] = { '\0' };
				snprintf(szTmp, sizeof(szTmp), "[%d,%d]", pattrId, attrVal);
				strLog += szTmp;
			}

			pPlayer->SetAttrPACache(pattrId, attrVal);
			//LogDebugFmtPrint("[logic] +++++++++++++++++++++++++CalcEquipAttr+++++++++++++++++++%d,%llu", pattrId, attrVal);
		}
	}
	LogDebugFmtPrint("[logic] PackagePart::CalcEquipAttr...cid:%llu, %s ",m_pMaster->GetCid(), strLog.c_str());

	if (bSync)
	{
		pPlayer->SynAttrToClient();
	}
	return true;
}

//计算套装属性
void PackagePart::CalcSuitAttr(MAP_UINT32_VEC_UINT32 &suitVec, MAP_INT32_FLOAT &attr, int32_t nPNumEquipBegin, int32_t nPNumEquipEnd)
{
	MAP_UINT32_VEC_UINT32::iterator iter = suitVec.begin();
	for (; iter != suitVec.end(); ++iter)
	{
		int32_t nSuitAttrSize = (int32_t)iter->second.size();
		const EquipSuitCfgInfo *pEquipSuitCfg = g_GetEquipSuitCfgTable()->GetEquipSuitCfgInfo(iter->first);
		if (nullptr != pEquipSuitCfg && nSuitAttrSize > 0)
		{
			const EquipSuitAttributeCfgInfo *pSuitAttrCfg = nullptr;
			VecEquipSuitAttributeCfg::const_iterator iterSuitAttr = pEquipSuitCfg->vecEquipSuitAttributeCfg.begin();
			for (; iterSuitAttr != pEquipSuitCfg->vecEquipSuitAttributeCfg.end(); ++iterSuitAttr)
			{
				const EquipSuitAttributeCfgInfo &attr = (*iterSuitAttr);
				if (attr.sctivation > 0 && nSuitAttrSize >= attr.sctivation)
					pSuitAttrCfg = &attr;
			}
			if (nullptr == pSuitAttrCfg)
			{
				continue;
			}

			string attrStr = pSuitAttrCfg->value;
			string tmpStr;
			int32_t pos = 0;
			int32_t pos_t = 0;
			int32_t attrId = 0;
			int32_t attrValue = 0;
			int32_t nPAttr = 0;

			while (true)
			{
				pos = attrStr.find(';');
				if (pos >= 0)
				{
					tmpStr = attrStr.substr(0, pos);
					pos_t = tmpStr.find(',');
					if (pos_t < 0)	break;
					attrId = atoi(tmpStr.substr(0, pos_t).c_str());
					attrValue = atoi(tmpStr.substr(pos_t + 1, tmpStr.length() - pos_t - 1).c_str());
					nPAttr = g_GetAttrMgr()->GetPlayerFightModlePAttr(enFightAttrModule_Equip,attrId);
					if (nPAttr > nPNumEquipBegin && nPAttr < nPNumEquipEnd)
						attr[nPAttr] += attrValue;
					attrStr = attrStr.substr(pos + 1, attrStr.length() - pos - 1);
				}
				else
				{
					pos_t = attrStr.find(',');
					if (pos_t < 0)	break;
					attrId = atoi(attrStr.substr(0, pos_t).c_str());
					attrValue = atoi(attrStr.substr(pos_t + 1, attrStr.length() - pos_t - 1).c_str());
					nPAttr = g_GetAttrMgr()->GetPlayerFightModlePAttr(enFightAttrModule_Equip,attrId);
					if (nPAttr > nPNumEquipBegin && nPAttr < nPNumEquipEnd)
						attr[nPAttr] += attrValue;
					break;
				}
			}
		}
	}
}

//神装、装备
uint16_t PackagePart::SetEquipByIndex(uint8_t byPos, CEquip *pItem, EEquipType eType)
{
	if (!ValidEquipPos(byPos))
	{
		return 0;
	}
	if (eType == EEquipType_Equip)
	{
		m_vecPlayerEquip[byPos] = pItem;
	}
	else if (eType == EEquipType_GodEquip)
	{
		m_vecPlayerGodEquip[byPos] = pItem;
	}
	
	return byPos;
}

//添加装备更新信息
bool PackagePart::AddPlayerEquipUpdateInfo(CItemBase *pItem, PlayerEquipUpdateRet &ret, bool bDel/* = false*/)
{
	if (nullptr == pItem)
	{
		return false;
	}
	ItemProtoInfo *protoItemInfo = ret.add_update();
	if (nullptr != protoItemInfo)
	{
		SetUpdateItemInfo(pItem, protoItemInfo, bDel);
	}
	return true;
}

inline int32_t ConverPos(int32_t byPos)
{
	if (EEquipPos_ring_ex == byPos)
		return EEquipPos_ring;
	if (EEquipPos_bracer_ex == byPos)
		return EEquipPos_bracer;
	return byPos;
}

//获取神印石技能信息
bool PackagePart::GetHolySkillParam(uint32_t nHolyItemID, uint32_t &nHolySkillID, uint32_t &nHolySKillLev, uint32_t &nHolySkillCd)
{
	const ItemItemCfgInfo *pHolyItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(nHolyItemID);
	if (nullptr == pHolyItemCfg)
	{
		LogErrFmtPrint("[logic] PackagePart::GetHolySkillParam...nullptr == pHolyItemCfg  itemid:%u ", nHolyItemID);
		return false;
	}

	/*if (pHolyItemCfg->subType < (int32_t)EItemSubType::EItemSubType_holystone_begin
		|| pHolyItemCfg->subType >(int32_t)EItemSubType::EItemSubType_holystone_end
		)
	{
		//非神印石
		LogErrFmtPrint("[logic] PackagePart::GetHolySkillParam...item is not holy stone..  itemid:%u,subtype:%d ", nHolyItemID, pHolyItemCfg->subType);
		return false;
	}
	if (pHolyItemCfg->functionType != (int32_t)EItemFuncType::EItemFuncType_AttachSkill && pHolyItemCfg->functionType != (int32_t)EItemFuncType::EItemFuncType_passiveSkill)
	{
		LogErrFmtPrint("[logic] PackagePart::GetHolySkillParam...holy stone functiontype error..  itemid:%u,functionType:%d ", nHolyItemID, pHolyItemCfg->functionType);
		return false;
	}*/

	if (pHolyItemCfg->subType < (int32_t)EItemSubType::EItemSubType_dy_rune_begin || pHolyItemCfg->subType >(int32_t)EItemSubType::EItemSubType_yk_rune_end)
	{
		//非符文(神印石)
		LogErrFmtPrint("[logic] PackagePart::GetHolySkillParam...item is not holy stone..  itemid:%u,subtype:%d ", nHolyItemID, pHolyItemCfg->subType);
		return false;
	}

	VEC_INT32 vecHolyPara;
	vecHolyPara.clear();
	CommonApi::SplitStrToVecInt(pHolyItemCfg->functionValue, ",", &vecHolyPara);
	if (vecHolyPara.size() < 2)
	{
		LogErrFmtPrint("[logic] PackagePart::GetHolySkillParam...holy stone functionvalue param error..  itemid:%u, functionvalue:%s ", nHolyItemID, pHolyItemCfg->functionValue.c_str());
		return false;
	}
	nHolySkillID = vecHolyPara.at(0);
	const SkillSkillCfgInfo *pHolySkillCfg = g_GetSkillSkillCfgTable()->GetSkillSkillCfgInfo(nHolySkillID);
	if (nullptr == pHolySkillCfg)
	{
		nHolySkillID = 0;
		LogErrFmtPrint("[logic] PackagePart::GetHolySkillParam...nullptr == pDressHolySkillCfg..  itemid:%u, skillid:%u ", nHolyItemID, nHolySkillID);
		return false;
	}
	nHolySKillLev = vecHolyPara.at(1);
	nHolySkillCd = pHolySkillCfg->cd;

	return true;
}

//同步装备数据到中心服
void PackagePart::SyncPlayerEquip(VEC_PLAYER_EQUIP &vecUpdateEquip, bool bAll /*= false*/)
{
	if (vecUpdateEquip.size() == 0)
	{
		return;
	}
	LogicToCenterCharSync sync;
	sync.set_charid(m_pMaster->GetCid());
	if (bAll)
	{
		sync.set_all_equip(1);
	}
	VEC_PLAYER_EQUIP::iterator iter = vecUpdateEquip.begin();
	for (; iter != vecUpdateEquip.end(); ++iter)
	{
		CEquip *pEquip = (*iter);
		if (nullptr != pEquip)
		{
			ItemProtoInfo *proto = sync.add_equip();
			if (nullptr != proto)
			{
				SetUpdateItemInfo(pEquip, proto);
			}
		}
	}
	g_GetLogicService()->SendDataToCenter(EMODULE_ID_SERV_SYS,CENTER_SERVER_PROTOCOL_LOGIC_TO_CENTER_CHAR_ATTR_SYNC, &sync);
}

//是否在冷却中  itemId_cdGroupId: 物品ID或者冷却组ID
bool PackagePart::IsInCd(uint32_t itemId_cdGroupId)
{
	uint64_t curMsec = Time::Now().UnixMSec();
	int32_t cdMsec = g_GetItemCfgMgr()->GetItemOrGroupCd(itemId_cdGroupId);
	MAP_UINT32_UINT64::iterator iter = m_mapItemCd.find(itemId_cdGroupId);
	if (iter != m_mapItemCd.end())
	{
		if (curMsec - iter->second <= (uint64_t)cdMsec)//在CD中
		{
			return true;
		}
		//不在cd中了直接删除
		m_mapItemCd.erase(iter);
	}
	return false;
}

//更新冷却
void PackagePart::UpdateCd(uint32_t itemId_cdGroupId)
{
	uint64_t curMsec = Time::Now().UnixMSec();
	m_mapItemCd[itemId_cdGroupId] = curMsec;
}

//检查所有的
void PackagePart::CheckAllCd()
{
	uint64_t curMsec = Time::Now().UnixMSec();
	MAP_UINT32_UINT64::iterator iter = m_mapItemCd.begin();
	while (iter != m_mapItemCd.end())
	{
		int32_t cdMsec = g_GetItemCfgMgr()->GetItemOrGroupCd(iter->first);
		if (curMsec - iter->second > (uint64_t)cdMsec)
		{
			iter = m_mapItemCd.erase(iter);
			continue;
		}
		++iter;
	}
}

//清空索引记录
void PackagePart::ClearIdxRecord()
{
	m_setIdxRecord.clear();
}

//get索引记录
SET_UINT16& PackagePart::GetIdxRecord()
{
	return m_setIdxRecord;
}

//外观改变事件
void PackagePart::FacadeChange(bool calcRefine)
{
	ChangeFacadeEvent facadeEvent;
	facadeEvent.cid = m_pMaster->GetCid();
	m_equipFacade.sFacade.Clear();

	if (calcRefine)
	{
		SET_UINT32 lel5Set;
		SET_UINT32 lel10Set;
		SET_UINT32 lel15Set;
		m_equipFacade.wEffectid = EeEquipEffectTypeID_None;
		m_equipFacade.bEffectid = EBodyEffectTypeID_None;
		for (uint8_t i = EEquipPos_none + 1; i <= EEquipPos_talisman; ++i)
		{
			CEquip *pEquip = GetEquip(i);
			if (nullptr == pEquip)
				continue;

			if (i == EEquipPos_weapon)
			{
				m_equipFacade.wEffectid = pEquip->GetRefineLev() >= REFINE_EFFECT_LEVEL_TOP ? EeEquipEffectTypeID_C : (pEquip->GetRefineLev() >= REFINE_EFFECT_LEVEL_MID ? EeEquipEffectTypeID_B : (pEquip->GetRefineLev() >= REFINE_EFFECT_LEVEL_LOW ? EeEquipEffectTypeID_A : EeEquipEffectTypeID_None));
				continue;
			}
			
			if (pEquip->GetRefineLev() >= REFINE_EFFECT_LEVEL_LOW)
				lel5Set.insert(pEquip->GetItemID());
			if (pEquip->GetRefineLev() >= REFINE_EFFECT_LEVEL_MID)
				lel10Set.insert(pEquip->GetItemID());
			if (pEquip->GetRefineLev() >= REFINE_EFFECT_LEVEL_TOP)
				lel15Set.insert(pEquip->GetItemID());
		}

		EBodyEffectTypeID b5 = lel5Set.size() >= REFINE_EFFECT_NUM_TOP ? EBodyEffectTypeID_C : (lel5Set.size() >= REFINE_EFFECT_NUM_MID ? EBodyEffectTypeID_B : (lel5Set.size() >= REFINE_EFFECT_NUM_LOW ? EBodyEffectTypeID_A : EBodyEffectTypeID_None));
		EBodyEffectTypeID b10 = lel10Set.size() >= REFINE_EFFECT_NUM_TOP ? EBodyEffectTypeID_F : (lel10Set.size() >= REFINE_EFFECT_NUM_MID ? EBodyEffectTypeID_E : (lel10Set.size() >= REFINE_EFFECT_NUM_LOW ? EBodyEffectTypeID_D : EBodyEffectTypeID_None));
		EBodyEffectTypeID b15 = lel15Set.size() >= REFINE_EFFECT_NUM_TOP ? EBodyEffectTypeID_I : (lel15Set.size() >= REFINE_EFFECT_NUM_MID ? EBodyEffectTypeID_H : (lel15Set.size() >= REFINE_EFFECT_NUM_LOW ? EBodyEffectTypeID_G : EBodyEffectTypeID_None));
		EBodyEffectTypeID bodyEffectId = max(max(b5, b10), b15);
		m_equipFacade.bEffectid = bodyEffectId;
	}

	if (m_equipFacade.showType == EEquipType_Equip)
	{
		m_equipFacade.sFacade.clothesId = facadeEvent.clothesId = m_equipFacade.clothesId;
		m_equipFacade.sFacade.weaponId = facadeEvent.weapoonId = m_equipFacade.weaponId;
		m_equipFacade.sFacade.wingId = facadeEvent.wingId = m_equipFacade.wingId;
		m_equipFacade.sFacade.runeDWId = facadeEvent.runeDWId = m_equipFacade.runeDWId;
		m_equipFacade.sFacade.runeYKId = facadeEvent.runeYKId = m_equipFacade.runeYKId;
		m_equipFacade.sFacade.wEffectid = m_equipFacade.wEffectid;
		m_equipFacade.sFacade.bEffectid = m_equipFacade.bEffectid;
	}
	else if (m_equipFacade.showType == EEquipType_GodEquip)
	{
		m_equipFacade.sFacade.weaponId = facadeEvent.weapoonId = m_equipFacade.godWeaponId > 0 ? m_equipFacade.godWeaponId : m_equipFacade.weaponId;
		m_equipFacade.sFacade.runeDWId = facadeEvent.runeDWId = m_equipFacade.godWeaponId > 0 ? 0 : m_equipFacade.runeDWId;
		m_equipFacade.sFacade.clothesId = facadeEvent.clothesId = m_equipFacade.godClothesId > 0 ? m_equipFacade.godClothesId : m_equipFacade.clothesId;
		m_equipFacade.sFacade.runeYKId = facadeEvent.runeYKId = m_equipFacade.godClothesId > 0 ? 0 : m_equipFacade.runeYKId;
		m_equipFacade.sFacade.wingId = facadeEvent.wingId = m_equipFacade.wingId;
		m_equipFacade.sFacade.wEffectid = m_equipFacade.godWeaponId <= 0 ? m_equipFacade.wEffectid : EeEquipEffectTypeID_None;
		m_equipFacade.sFacade.bEffectid = m_equipFacade.godClothesId <= 0 ? m_equipFacade.bEffectid : EBodyEffectTypeID_None;
	}
	else
	{
		m_equipFacade.sFacade.fashionId = facadeEvent.fashionId = m_equipFacade.fashionId;
		m_equipFacade.sFacade.clothesId = facadeEvent.clothesId = m_equipFacade.fashionId > 0 ? 0 : m_equipFacade.clothesId;
		m_equipFacade.sFacade.runeYKId = facadeEvent.runeYKId = m_equipFacade.fashionId > 0 ? 0 : m_equipFacade.runeYKId;
		m_equipFacade.sFacade.weaponId = facadeEvent.weapoonId = m_equipFacade.weaponId;
		m_equipFacade.sFacade.wingId = facadeEvent.wingId = m_equipFacade.wingId;
		m_equipFacade.sFacade.runeDWId = facadeEvent.runeDWId = m_equipFacade.runeDWId;
		m_equipFacade.sFacade.wEffectid = m_equipFacade.wEffectid;
		m_equipFacade.sFacade.bEffectid = m_equipFacade.fashionId <= 0 ? m_equipFacade.bEffectid : EBodyEffectTypeID_None;
	}

	uint32_t horseId = 0;
	HorsePart* pHorsePart = dynamic_cast<HorsePart*>(m_pMaster->GetPart(PART_HORSE));
	if (pHorsePart)
	{
		horseId = pHorsePart->GetCurHorseId();
	}

	g_GetEvent()->FireExecute(EVENT_FACADE_CHANGE, m_pMaster->GetCid(), m_pMaster->CreatureKind(), &facadeEvent, sizeof(ChangeFacadeEvent));

	LogicToCenterCharFacadeSync sync;
	sync.set_charid(m_pMaster->GetCid());

	CharFacadeProto *pFacade = sync.mutable_facade();
	GetFacade(*pFacade);
	pFacade->set_cur_horse_id(horseId);
	g_GetLogicService()->SendDataToCenter(EMODULE_ID_SERV_SYS, LOGIC_TO_CENTER_SYNC_FACADE_DATA, &sync);

	FacadeBroadcast broadcast;
	broadcast.set_charid(m_pMaster->GetCid());
	broadcast.mutable_facade()->CopyFrom(sync.facade());
	m_pMaster->BroadCastData(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_FACADE_BROADCAST, (ProtoBufBase*)&broadcast, true);
}
//////////////////////////////////////////////////////////////////////////


////////////////////////////////////  玩家背包逻辑  //////////////////////////////////////
//标签页信息
void PackagePart::LabelInfo()
{
	PackageLabelInfoRet ret;
	ret.set_expand_grid(m_nExpandNum);
	ret.set_init_all_grid(PACKAGE_INIT_GRID_NUM);

	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_LABEL_INFO, &ret);
}
//单个标签页数据
bool PackagePart::LabelItemInfo(uint8_t byLabel)
{
	PackageInfoRet ret; 
	ret.set_package_label(byLabel);
	

	int8_t byLabelEx = EPackageLabel_all;
	if (EPackageLabel_task == byLabel)
	{
		byLabelEx = EPackageLabel_task;
	}
	uint16_t nStartIdx = GetLabelStartIdx(byLabelEx);
	uint16_t nEndIdx = GetLabelEndIdx(byLabelEx);
	for (uint16_t i = nStartIdx; i <= nEndIdx; ++i)
	{
		CItemBase *pItem = GetItemByIndex(i);
		if (nullptr != pItem)
		{
			if (EPackageLabel_equip == byLabel)
			{
				const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pItem->GetItemID());
				if (nullptr != pEquipCfg)
				{
					ItemProtoInfo *protoInfo = ret.add_item_list();
					if (nullptr != protoInfo)
					{
						SetUpdateItemInfo(pItem, protoInfo);
					}
				}
			}
			else
			{
				const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItem->GetItemID());
				if (nullptr != pItemCfg && byLabel == pItemCfg->itemType)
				{
					ItemProtoInfo *protoInfo = ret.add_item_list();
					if (nullptr != protoInfo)
					{
						SetUpdateItemInfo(pItem, protoInfo);
					}
				}
			}
		}
	}
	return m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_INFO, &ret);
}
//信息
void PackagePart::ItemInfo(const char *data, uint32_t len)
{
	PackageInfoReq req;
	if (!req.ParseFromArray(data,len))
	{
		LogErrFmtPrint("[logic] PackagePart::ItemInfo  PackageInfoReq parse failed....");
		return;
	}
	uint8_t byLabel = (uint8_t)req.package_label();
	LabelItemInfo(byLabel);
}
//整理
void PackagePart::ItemSort(const char *data, uint32_t len)
{
	PackageSortRet ret;
	uint64_t nCurTime = Time::Now().sec();
	if (nCurTime - m_nLastSortTime < 3)
	{
		//冷却中RET_PACKAGE_SORT_IN_COOL			= 408;	//整理在冷却中
		ret.set_retcode(RET_PACKAGE_SORT_IN_COOL);
	}
	else
	{
		if (!BagItemSort(EPackageType_packge))
		{
			ret.set_retcode(RET_FAIL);
		}
		else
		{
			//设置最近一次整理时间
			m_nLastSortTime = nCurTime;
			//先返回整理成功
			ret.set_retcode(RET_SUCCESS);
		}		
	}
	//先返回整理结果
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_SORT, &ret);
	//
	if (RET_SUCCESS == ret.retcode())
	{
		//整理成功之后返回标签页数据
		LabelItemInfo(EPackageLabel_equip);
		LabelItemInfo(EPackageLabel_material);
		LabelItemInfo(EPackageLabel_sundry);
		//藏宝图那边的处理
		uint16_t begIdx = GetLabelStartIdx(EPackageLabel_all);
		uint16_t endIdx = GetLabelEndIdx(EPackageLabel_all);
		for (uint16_t i = begIdx; i <= endIdx; ++i)
		{
			CItemBase *pItem = GetItemByIndex(i);
			if (nullptr == pItem)
			{
				continue;
			}
			if (pItem->ActiveStatus())
			{
				//这里需要通知藏宝图那边，激活的
				TreasurePart *pPart = dynamic_cast<TreasurePart*>(m_pMaster->GetPart(PART_TREASURE));
				if (nullptr != pPart)
				{
					pPart->SetActiveIdx(pItem->GetIndex());
				}
				else
				{
					LogErrFmtPrint("[logic] PackagePart::ItemSort...nullptr == pPart....");
				}
			}
		}	
	}
}
//出售
void PackagePart::ItemSell(const char *data, uint32_t len)
{
	PackageSellReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] PackagePart::ItemSell  PackageSellReq parse failed....");
		return;
	}
	uint16_t nsize = (uint16_t)req.sell_size();
	if (nsize < 1)
	{
		return;
	}
	bool bSingle = false;
	uint16_t nSingleNum = 0;
	if (1 == nsize)
	{
		//出售单个物品
		const ItemSellProto &sell_item = req.sell(0);
		if (!sell_item.has_num() || sell_item.num() < 1)
		{
			//没有数量或者数量错误
			return;
		}
		nSingleNum = sell_item.num();
		bSingle = true;
	}
	PackageSellRet ret;
	ret.set_retcode(RET_SUCCESS);
	VEC_PACKAGE_ITEM buyBackVec;
	MAP_UINT16_INT32 mapIdxNum;
	mapIdxNum.clear();
	uint32_t nTotalMoney = 0;
	for (uint16_t i = 0; i < nsize; ++i)
	{
		const ItemSellProto &sell_item = req.sell(i);
		uint16_t idx = (uint16_t)sell_item.index();
		CItemBase *pItem = GetItemByIndex(idx);
		if (nullptr == pItem)
		{
			//物品不存在 RET_PACKAGE_ITEM_NOT_EXITS
			LogErrFmtPrint("[logic] PackagePart::ItemSell index item not exists....index:%d ", idx);
			ret.set_retcode(RET_PACKAGE_ITEM_NOT_EXITS);
			break;
		}
		if (bSingle && pItem->GetNum() < nSingleNum)
		{
			//数量不够 RET_PACKAGE_ITEM_NUM_LACK
			ret.set_retcode(RET_PACKAGE_ITEM_NUM_LACK);
			break;
		}
		if (!g_GetItemMgr()->CanSell(pItem->GetItemID(),pItem->GetBind()))
		{
			//不能出售 RET_PACKAGE_ITEM_CAN_NOT_SELL
			ret.set_retcode(RET_PACKAGE_ITEM_CAN_NOT_SELL);
			break;
		}

		EItemType byType = EItemType_common;
		uint16_t nSellNum = pItem->GetNum();
		const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItem->GetItemID());
		if (nullptr != pItemCfg)
		{
			if (bSingle)
			{
				nSellNum = nSingleNum;
			}
			nTotalMoney += pItemCfg->sellPrice * nSellNum;
		}
		else
		{
			const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pItem->GetItemID());
			if (nullptr == pEquipCfg)
			{
				//物品不存在
				LogErrFmtPrint("[logic] PackagePart::ItemSell  item not exists....index:%d itemid:%u ", idx, pItem->GetItemID());
				ret.set_retcode(RET_PACKAGE_ITEM_NOT_EXITS);
				break;
			}
			nTotalMoney += pEquipCfg->sellPrice;
			byType = EItemType_equip;
		}
		MAP_UINT16_INT32::iterator iter = mapIdxNum.find(idx);
		if (iter != mapIdxNum.end())
		{
			//重复索引
			LogErrFmtPrint("[logic] PackagePart::ItemSell repeate index....index:%d ", idx);
			ret.set_retcode(RET_FAIL);
			break;
		}
		mapIdxNum[idx] = nSellNum;

		CItemBase *pBuyBackItem = g_GetItemMgr()->MakeItemObj(byType);
		if (nullptr == pBuyBackItem)
		{
			LogErrFmtPrint("[logic] PackagePart::ItemSell nullptr == pBuyBackItem....fail");
			ret.set_retcode(RET_FAIL);
			break;
		}
		pBuyBackItem->CopyFrom(pItem);
		pBuyBackItem->SetNum(nSellNum);
		buyBackVec.push_back(pBuyBackItem);

		if (bSingle)
		{
			break;
		}
	}
	
	if (RET_SUCCESS == ret.retcode())
	{
		SItemSourceParam sourceParam;
		if (RemoveItem(mapIdxNum, sourceParam))
		{
			//增加金钱，后面添加  nTotalMoney
			//m_pMaster->AddAttr(C_GOLD, nTotalMoney, true);
			m_pMaster->AddSourceAttr(C_GOLD, nTotalMoney, true, S_PACKAGE);
			UpdateBuyBack(buyBackVec);
		}
		else
		{
			ret.set_retcode(RET_FAIL);
		}
	}

	if (ret.retcode() != RET_SUCCESS)
	{
		//释放 buyBackVec
		for (VEC_PACKAGE_ITEM::iterator iter = buyBackVec.begin(); iter != buyBackVec.end(); ++iter)
			g_GetItemMgr()->FreeItemObj(*iter);
		buyBackVec.clear();
	}
	
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_SELL, &ret);
}	

void PackagePart::UpdateBuyBack(VEC_PACKAGE_ITEM &vec)
{
	if (vec.size() <= 0)	return;
	for (VEC_PACKAGE_ITEM::iterator iter = vec.begin(); iter != vec.end(); ++iter)
	{
		m_dequeRebuyItem.push_front(*iter);
	}
	while (m_dequeRebuyItem.size() > 25)
	{
		CItemBase* pItem = m_dequeRebuyItem.back();
		if (pItem)
		{
			g_GetItemMgr()->FreeItemObj(pItem);
		}
		m_dequeRebuyItem.pop_back();
	}

	BuyBackUpdate update;
	for (std::deque<CItemBase*>::iterator iter = m_dequeRebuyItem.begin(); iter != m_dequeRebuyItem.end(); ++iter)
	{
		ItemProtoInfo *itemProto = update.add_item_list();
		if (nullptr != itemProto)
		{
			g_GetItemMgr()->SetItemProtoInfo(*iter, itemProto);
		}
		else
		{
			LogErrFmtPrint("[logic] PackagePart::UpdateBuyBack nullptr == itemProto....fail");
		}
	}
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_REBUY_UPDATE, &update);
}

//拾取掉落
void PackagePart::PickupDrop(const char *data, uint32_t len)
{
	PakcagePickupDropReq req;
	if (!req.ParseFromArray(data,len))
	{
		LogErrFmtPrint("[logic] PackagePart::PickupDrop  PakcagePickupDropReq parse failed....");
		return;
	}
	uint64_t nCid = m_pMaster->GetCid();
	int32_t nsize = req.droplst_size();
	MAP_Drop mapDrop;
	mapDrop.clear();
	VEC_ITEM_PROTO_EX vecProtoAdd;
	vecProtoAdd.clear();
	VEC_ITEM_PROTO_EX vecProtoPick;
	vecProtoPick.clear();
	uint32_t nGold = 0;
	int32_t addGoldRate = 0;
	float fcoef = 0.0;
	//buff那边可能会增加金币掉率
	BuffPart *pBuffPart = dynamic_cast<BuffPart*>(m_pMaster->GetPart(PART_BUFF));
	if (nullptr != pBuffPart)
	{
		addGoldRate = pBuffPart->GetBuffDropGoldPercent();
		fcoef = ((float)addGoldRate / (float)DROP_RAND_BASE_NUM);
	}
	Scene *pScene = m_pMaster->GetScene();
	if (nullptr == pScene)
	{
		LogErrFmtPrint("[logic] PackagePart::PickupDrop...nullptr == pScene...cid:%lu ", nCid);
		return;
	}
	if (m_pMaster->IsDead())
	{
		//已经死亡
		LogErrFmtPrint("[logic] PackagePart::PickupDrop...player is dead...cid:%lu ", nCid);
		return;
	}
	//
	PakcagePickupDropRet rsp;
	rsp.set_retcode(RET_SUCCESS);
	
	uint32_t dropGold = 0;
	bool eventFalg = false;
	uint32_t eventItemId = 0;
	for (int32_t i = 0; i < nsize; ++i)
	{
		bool dropRes = false; //拾取结果
		uint64_t dropId = req.droplst(i);
		Drop *pDrop = pScene->GetDrop(dropId);
		if (nullptr != pDrop && pDrop->CanPickUp(nCid))
		{
			if (nullptr != pDrop->GetDropItem())
			{
				const SDropSourcePram &dropSource = pDrop->GetDropSource();
				ItemProtoInfo protoAdd;
				if (g_GetItemMgr()->SetItemProtoInfo(pDrop->GetDropItem(), &protoAdd))
				{
					vecProtoAdd.clear();
					vecProtoAdd.push_back(protoAdd);
					SItemSourceParam sourceParam;
					sourceParam.source = S_Drop;
					if (EDropSource_Act == dropSource.source)
					{
						const ActivityDailyCfgInfo *pActivityCfg = g_GetActivityDailyCfgTable()->GetActivityDailyCfgInfo(dropSource.sourceVal);
						if (nullptr != pActivityCfg)
						{
							sourceParam.notifyVal = pActivityCfg->activeId;
							if (ATI_WORLD_BOSS == pActivityCfg->typeId)
							{
								sourceParam.notifySource = ENotifyType_Item_WorldBoss;
							}
							else if (ATI_CHAOS_DRAGON == pActivityCfg->typeId)
							{
								sourceParam.notifySource = ENotifyType_Item_ChaosDragon;
							}
							else if (ATI_LOST_CITY == pActivityCfg->typeId)
							{
								sourceParam.notifySource = ENotifyType_Item_LostCity;
							}
							else if (ATI_SON_OF_KILLING == pActivityCfg->typeId)
							{
								sourceParam.notifySource = ENotifyType_Item_SonOfKilling;
							}
							else if (ATI_MONS_ATTACK_CITY == pActivityCfg->typeId)
							{
								sourceParam.notifySource = ENotifyType_Item_MonsAttackCity;
							}
							else if (ATI_CLOUD == pActivityCfg->typeId)
							{
								sourceParam.notifySource = ENotifyType_Item_Cloud;
							}
							else if (ATI_NOLIN_TREASURE == pActivityCfg->typeId)
							{
								sourceParam.notifySource = ENotifyType_Item_NolinTreasure;
							}
							else if (ATI_ESCORT == pActivityCfg->typeId)
							{
								sourceParam.notifySource = ENotifyType_Item_UnionEscort;
							}
						}
					}
					else if (EDropSource_Dup == dropSource.source)
					{
						const DuplicateDuplicateCfgInfo *pDuplicateCfg = g_GetDuplicateDuplicateCfgTable()->GetDuplicateDuplicateCfgInfo(dropSource.sourceVal);
						if (nullptr != pDuplicateCfg)
						{
							sourceParam.notifyVal = pDuplicateCfg->duplicateID;
							if ((int32_t)EDuplicateType::EDuplicateType_Story == pDuplicateCfg->duplicateType)
							{
								sourceParam.notifySource = ENotifyType_Item_StoryDup;
							}
							else if ((int32_t)EDuplicateType::EDuplicateType_Ladder == pDuplicateCfg->duplicateType)
							{
								sourceParam.notifySource = ENotifyType_Item_LadderDup;
							}
						}
					}
					
					if (AddItem(vecProtoAdd, sourceParam))
					{
						vecProtoPick.push_back(protoAdd);
						//
						dropRes = true;
						//成功拾取
						mapDrop[dropId] = pDrop;
						//
						const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(protoAdd.item_id());
						if (nullptr != pItemCfg && ((int32_t)EItemSubType::EItemSubType_special_kill_stone == pItemCfg->subType
							|| (int32_t)EItemSubType::EItemSubType_special_remains_god == pItemCfg->subType
							|| (int32_t)EItemSubType::EItemSubType_special_light_camp_flag == pItemCfg->subType
							|| (int32_t)EItemSubType::EItemSubType_special_dark_camp_flag == pItemCfg->subType))
						{
							eventFalg = true;
							eventItemId = (uint32_t)pItemCfg->id;
						}
					}					
				}
			}
			else if (pDrop->GetDropGold() > 0)
			{
				dropRes = true;
				//成功拾取
				mapDrop[dropId] = pDrop;
				//
				uint32_t curGold = pDrop->GetDropGold();
				nGold += curGold;
				//
				dropGold += curGold;

				//buff 金币加成
				if (addGoldRate > 0)
				{
					int32_t addGold = (int32_t)(curGold * fcoef);
					nGold += addGold;
					dropGold += addGold;
				}
			}
		}

		if (!dropRes)
		{
			rsp.add_fail_list(dropId);
		}
	}
	//金币
	if (nGold > 0)
	{
		//m_pMaster->AddAttr(C_GOLD, (int64_t)nGold, true);
		m_pMaster->AddSourceAttr(C_GOLD, (int64_t)nGold, true, S_PACKAGE);
	}

	//设置物品已经拾取过了
	MAP_Drop::iterator iterDropDel = mapDrop.begin();
	for (; iterDropDel != mapDrop.end(); ++iterDropDel)
	{
		Drop *pDrop = iterDropDel->second;
		if (nullptr != pDrop)
		{
			rsp.add_drop_list(pDrop->GetCid());
			pDrop->Pick();
		}
	}
	mapDrop.clear();

	uint32_t sceneId = m_pMaster->GetSceneId();
	IDuplicate *pDuplicate = g_GetDuplicateMgr()->GetDuplicate(sceneId);
	if (nullptr != pDuplicate)
	{
		Player *pPlayer = dynamic_cast<Player*>(m_pMaster);
		if (nullptr != pPlayer)
		{
			string strName = pPlayer->GetName();
			pDuplicate->PickDrop(pPlayer->GetCid(), strName, pPlayer->GetAttr(C_PROF),pPlayer->GetAttr(C_GENDER), vecProtoPick);
		}		
	}

	//目前只是拾取杀戮之石以及神之遗骸、阵营旌旗需要发事件
	if (eventFalg)
	{
		PickItemEvent pickEvent;
		pickEvent.itemId = eventItemId;
		pickEvent.pickerId = m_pMaster->GetCid();
		g_GetEvent()->FireExecute(EVENT_PICK_ITEM, m_pMaster->GetCid(), m_pMaster->CreatureKind(), &pickEvent, sizeof(pickEvent));
	}
	//
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_PICKUP_DROP, &rsp);
}

//冷却信息
void PackagePart::CoolInfo(const char *data, uint32_t len)
{
	PackageCoolRsp rsp;
	uint64_t curMsec = Time::Now().UnixMSec();
	MAP_UINT32_UINT64::iterator iterCd = m_mapItemCd.begin();
	for (; iterCd != m_mapItemCd.end(); ++iterCd)
	{
		int32_t pastCd = (int32_t)(curMsec - iterCd->second);
		int32_t cdMsec = g_GetItemCfgMgr()->GetItemOrGroupCd(iterCd->first);
		int32_t left = (pastCd < cdMsec) ? (cdMsec - pastCd) : 0 ;
		if (left > 0)
		{
			PackageCoolProto *proto = rsp.add_cool();
			if (nullptr != proto)
			{
				proto->set_itemid_or_groupid(iterCd->first);
				proto->set_left_msec(left);
			}
		}	
	}
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_ITEM_CD_INFO, &rsp);
}

//使用
void PackagePart::ItemUse(const char *data, uint32_t len)
{
	PackageUseReq req;
	if (!req.ParseFromArray(data,len))
	{
		LogErrFmtPrint("[logic] PackagePart::ItemUse  PackageUseReq parse failed....");
		return;
	}
	uint16_t nIndex = (uint16_t)req.index();
	uint16_t nNum = 1;
	if (req.has_num())
	{
		nNum = (uint16_t)req.num();
	}
	if (!ValidIndex(nIndex))
	{
		return;
	}
	UseItemArgProto protoArg;
	if (req.has_arg())
	{
		protoArg.CopyFrom(req.arg());
	}
	int32_t ret = UseItem(nIndex, nNum, protoArg);
	PackageUseRet rsp;
	rsp.set_retcode(ret);
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_USE, &rsp);
}
//更新背包
void PackagePart::UpdatePackageInfo(PackageUpdateRet &protoUpdate)
{
	if (protoUpdate.item_list_size() > 0)
	{
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_UPDATE, &protoUpdate);
	}
}
//更新扩展
bool PackagePart::UpdatePackageExpand()
{
	PackageUpdateExpandRet ret;
	ret.set_expand_grid(m_nExpandNum);
	return m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_UPDATE_EXPAND, &ret);
}

//更新扩展仓库
bool PackagePart::UpdateStorageExpand()
{
	StorageExpandRsp rsp;
	rsp.set_retcode(RET_SUCCESS);
	rsp.set_expand_grid(m_storageExpand);
	return m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STORAGE_EXPAND, &rsp);
}

//////////////////////////////////////////////////////////////////////////


///////////////////////////////////// 玩家装备逻辑     /////////////////////////////////////
//装备信息
void PackagePart::EquipInfo(const char *data, uint32_t len)
{
	PlayerEquipInfoRet ret;
	for (uint8_t i = EEquipPos_none + 1; i < EEquipPos_limit; ++i)
	{
		CEquip *pEquip = GetEquip(i);
		if (nullptr != pEquip)
		{
			ItemProtoInfo *protoInfo = ret.add_equip_info();
			if (nullptr == protoInfo)
			{
				MMOLOG_FMT_ERROR("[logic] PackagePart::EquipInfo  nullptr == protoInfo....idx:%d ", i);
				continue;;
			}
			SetUpdateItemInfo(GetEquip(i), protoInfo);
		}

		CEquip *pGodEquip = GetEquip(i, EEquipType_GodEquip);
		if (nullptr != pGodEquip)
		{
			ItemProtoInfo *protoGodInfo = ret.add_god_equip_info();
			if (nullptr == protoGodInfo)
			{
				MMOLOG_FMT_ERROR("[logic] PackagePart::EquipInfo  nullptr == protoGodInfo....idx:%d ", i);
				continue;;
			}
			SetUpdateItemInfo(pGodEquip, protoGodInfo);
		}

		EquipSlot &slot = m_vecEquipSlot[i];
		if (slot.m_nIndex <= 0)		continue;
		EquipSlotProto *protoSlot = ret.add_equip_slot_info();
		if (nullptr == protoSlot)
		{
			MMOLOG_FMT_ERROR("[logic] PackagePart::EquipInfo  nullptr == protoSlot....idx:%d ", i);
			continue;;
		}
		SetEquipSlotInfo(slot, protoSlot);
	}

	for (VEC_PLAYER_FASHION::iterator it = m_vecPlayerFashion.begin(); it != m_vecPlayerFashion.end(); it++)
	{
		FashionProtoInfo *fashionProto = ret.add_fashion_info();
		if (fashionProto)
		{
			fashionProto->set_fashion_id((*it).fashionId);
			fashionProto->set_left_time(((*it).leftMin >= 0) ? (*it).leftMin * 60 : (*it).leftMin);
			//fashionProto->set_left_time((*it).leftMin * 60);
			fashionProto->set_is_dress((*it).isDress);
		}
	}

	ret.set_show_type(m_equipFacade.showType);
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_INFO, &ret);
}
//装备穿戴
void PackagePart::EquipDress(const char *data, uint32_t len)
{
	PlayerEquipDressReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] PlayerEquipDressReq parse failed....");
		return;
	}

	PlayerEquipDressRet ret;
	ret.set_retcode(RET_FAIL);
	ret.set_equip_type(req.equip_type());

	if (req.equip_type() != 0 && req.equip_type() != 1)
	{
		LogDebugFmtPrint("[logic] PackagePart::EquipDress  equip_type is error....equip_type:%d ", req.equip_type());
		m_pMaster->SendDataToClientEx(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_UNDRESS, &ret);
		return;
	}

	uint16_t nIndex = (uint16_t)req.index();
	if (!ValidIndex(nIndex))
	{
		LogDebugFmtPrint("[logic] PackagePart::EquipDress  index not valid....index:%d ", nIndex);
		ret.set_retcode(RET_EQUIP_EQUIP_POS_ERR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_DRESS, &ret);
		return;
	}
	if (!ValidLabelIndex(EPackageLabel_all, nIndex))
	{
		LogDebugFmtPrint("[logic] PackagePart::EquipDress  not equip index ....index:%d ", nIndex);
		ret.set_retcode(RET_EQUIP_EQUIP_POS_ERR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_DRESS, &ret);
		return;
	}

	CEquip *pPackageEquip = dynamic_cast<CEquip*>(GetItemByIndex(nIndex));
	if (nullptr == pPackageEquip)
	{
		ret.set_retcode(RET_EQUIP_EQUIP_NOT_EXIST);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_DRESS, &ret);
		return;
	}
	
	nIndex = pPackageEquip->GetIndex();
	if (!ValidLabelIndex(EPackageLabel_all,nIndex))
	{
		LogErrFmtPrint("[logic] PackagePart::EquipDress ValidLabelIndex return false...nIndex:%d " , nIndex);
		ret.set_retcode(RET_EQUIP_EQUIP_POS_ERR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_DRESS, &ret);
		return;
	}

	const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pPackageEquip->GetItemID());
	if (nullptr == pEquipCfg)
	{
		LogErrFmtPrint("[logic] nullptr == pEquipCfg equipid:%u ", pPackageEquip->GetItemID());
		ret.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_DRESS, &ret);
		return;
	}

	if (!ValidEquipPos((uint8_t)pEquipCfg->position))
	{
		LogErrFmtPrint("[logic] ValidEquipPos false ....equipid:%u  pos:%d ", pEquipCfg->id, pEquipCfg->position);
		ret.set_retcode(RET_EQUIP_EQUIP_POS_ERR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_DRESS, &ret);
		return;
	}
	
	bool bErr = false;
	uint8_t byDstPos = EEquipPos_none;
	if (EEquipPos_ring == pEquipCfg->position || EEquipPos_bracer == pEquipCfg->position)
	{
		//戒指和护腕有两个穿戴位置，所以必须传位置过来
		if (!req.has_pos())
		{
			LogErrFmtPrint("[logic] req.has_pos() return false ....equipid:%u  pos:%d ", pEquipCfg->id, pEquipCfg->position);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_DRESS, &ret);
			return;
		}
		byDstPos = (uint8_t)req.pos();
		if (EEquipPos_ring == pEquipCfg->position)
		{
			if (EEquipPos_ring != byDstPos && EEquipPos_ring_ex != byDstPos)
				bErr = true;
		}
		else
		{
			if (EEquipPos_bracer != byDstPos && EEquipPos_bracer_ex != byDstPos)
				bErr = true;
		}
	}
	else
	{
		byDstPos = (uint8_t)pEquipCfg->position;
	}

	if (!ValidEquipPos(byDstPos))
	{
		LogErrFmtPrint("[logic] ValidEquipPos false ....equipid:%u  byDstPos:%d ", pEquipCfg->id, byDstPos);
		ret.set_retcode(RET_EQUIP_EQUIP_POS_ERR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_DRESS, &ret);
		return;
	}

	int32_t nLevel = m_pMaster->GetAttr(C_LEVEL);
	if (nLevel < pEquipCfg->wearLevel)
	{
		ret.set_retcode(RET_LEVEL_LACK);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_DRESS, &ret);
		return;
	}

	if ((int32_t)m_pMaster->GetAttr(C_PROF) != pEquipCfg->profession)
	{
		ret.set_retcode(RET_PROF_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_DRESS, &ret);
		return;
	}

	if (bErr)
	{
		ret.set_retcode(RET_EQUIP_EQUIP_POS_ERR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_DRESS, &ret);
		return;
	}
	
	PackageUpdateRet update_ret;
	CEquip *pDressEquip = GetEquip(byDstPos, (EEquipType)req.equip_type());
	if (nullptr != pDressEquip)		//当前部位有装备 装备替换 宝石符文不动
	{
		pDressEquip->SetIndex(nIndex);
		if (!SetItemByIndex(nIndex, pDressEquip))
		{
			LogErrFmtPrint("[logic] PackagePart::EquipDress 11 SetItemByIndex false...index:%d ",nIndex);
		}

		if (req.equip_type() == EEquipType_Equip)
		{
			pPackageEquip->SetIndex(byDstPos);
			SetEquipByIndex(byDstPos, pPackageEquip, (EEquipType)req.equip_type());
			pPackageEquip->SetBind(g_GetItemMgr()->BindStateByDress(pPackageEquip->GetItemID(), pPackageEquip->GetBind())); //穿戴之后绑定状态

			VEC_UINT32 *pDressInlayVec = pDressEquip->GetInlay();
			VEC_UINT32 *pPackageInlayVec = pPackageEquip->GetInlay();
			pDressInlayVec->swap(*pPackageInlayVec);
			uint32_t tempHolyId = pDressEquip->GetHoly();
			pDressEquip->SetHoly(pPackageEquip->GetHoly());
			pPackageEquip->SetHoly(tempHolyId);

			UpdateEquipInfo(pPackageEquip, (EEquipType)req.equip_type());

			ItemProtoInfo itemProto;
			SetUpdateItemInfo(pDressEquip, &itemProto);
			ret.mutable_item_info()->CopyFrom(itemProto);
			ret.set_retcode(RET_SUCCESS);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_DRESS, &ret);

			CalcEquipAttr();
			VEC_PLAYER_EQUIP vecSync;
			vecSync.push_back(pPackageEquip);
			SyncPlayerEquip(vecSync);

			//if (!ValidEquipFacadePos(byDstPos) && packageItemId != dressItemId)		
			//	return;

			if (EEquipPos_clothes == byDstPos)
			{
				m_equipFacade.clothesId = pPackageEquip->GetItemID();
				FacadeChange(true);
			}
			else if (EEquipPos_weapon == byDstPos)
			{
				m_equipFacade.weaponId = pPackageEquip->GetItemID();
				FacadeChange(true);
			}
			else if (EEquipPos_wing == byDstPos)
			{
				m_equipFacade.wingId = pPackageEquip->GetItemID();
				FacadeChange(true);
			}
			StatisticsEquip();
			return;
		}
	}
	else
	{
		AddPackageUpdateInfo(pPackageEquip, update_ret, true);
		if (!SetItemByIndex(nIndex, nullptr))
		{
			LogErrFmtPrint("[logic] PackagePart::EquipDress 22 SetItemByIndex false...index:%d ", nIndex);
		}
	}
	pPackageEquip->SetIndex(byDstPos);
	SetEquipByIndex(byDstPos, pPackageEquip, (EEquipType)req.equip_type());
	pPackageEquip->SetBind(g_GetItemMgr()->BindStateByDress(pPackageEquip->GetItemID(),pPackageEquip->GetBind())); //穿戴之后绑定状态

	//更新装备
	UpdateEquipInfo(pPackageEquip, (EEquipType)req.equip_type());

	if (nullptr != pDressEquip)
	{
		ItemProtoInfo itemProto;
		SetUpdateItemInfo(pDressEquip, &itemProto);
		ret.mutable_item_info()->CopyFrom(itemProto);
	}
	ret.set_retcode(RET_SUCCESS);
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_DRESS, &ret);

	//LogDebugFmtPrint("[logic] PackagePart::EquipDress...byDstPos:%d , nIndex:%d ", byDstPos, nIndex);

	//更新背包
	UpdatePackageInfo(update_ret);

	//计算属性
	CalcEquipAttr();
	
	//同步装备属性
	if ((EEquipType)req.equip_type() == EEquipType_Equip)
	{
		VEC_PLAYER_EQUIP vecSync;
		vecSync.push_back(pPackageEquip);
		SyncPlayerEquip(vecSync);
		StatisticsEquip();
	}

	//if (!ValidEquipFacadePos(byDstPos) && packageItemId != dressItemId)		return;
	
	if (EEquipPos_clothes == byDstPos)
	{
		if ((EEquipType)req.equip_type() == EEquipType_Equip)
		{
			m_equipFacade.clothesId = pPackageEquip->GetItemID();
			m_equipFacade.runeYKId = pPackageEquip->GetHoly();
			if (pPackageEquip->GetHoly() > 0)
				AddRuneSkill(pPackageEquip->GetHoly());
		}
		else if ((EEquipType)req.equip_type() == EEquipType_GodEquip)
			m_equipFacade.godClothesId = pPackageEquip->GetItemID();
	}
	else if (EEquipPos_weapon == byDstPos)
	{
		if ((EEquipType)req.equip_type() == EEquipType_Equip)
		{
			m_equipFacade.weaponId = pPackageEquip->GetItemID();
			m_equipFacade.runeDWId = pPackageEquip->GetHoly();
			if (pPackageEquip->GetHoly() > 0)
				AddRuneSkill(pPackageEquip->GetHoly());
		}
		else if((EEquipType)req.equip_type() == EEquipType_GodEquip)
			m_equipFacade.godWeaponId = pPackageEquip->GetItemID();
	}
	else if (EEquipPos_wing == byDstPos)
	{
		m_equipFacade.wingId = pPackageEquip->GetItemID();
	}
	FacadeChange((EEquipType)req.equip_type() == EEquipType_Equip);
}

//是否已穿戴
bool PackagePart::IsEquipDress(uint32_t equipId)
{
	for (uint8_t i = EEquipPos_none + 1; i <= EEquipPos_talisman; ++i)
	{
		CEquip *pEquip = GetEquip(i);
		if (nullptr != pEquip && pEquip->GetItemID() == equipId)
			return true;

		CEquip *pGodEquip = GetEquip(i, EEquipType_GodEquip);
		if (nullptr != pGodEquip && pGodEquip->GetItemID() == equipId)
			return true;
	}

	return false;
}

//装备卸下
void PackagePart::EquipUnDress(const char *data, uint32_t len)
{
	PlayerEquipUndressReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] PlayerEquipUndressReq parse failed....");
		return;
	}

	PlayerEquipUndressRet ret;
	ret.set_retcode(RET_FAIL);

	if (req.equip_type() != 0 && req.equip_type() != 1)
	{
		LogErrFmtPrint("[logic] PackagePart::EquipUnDress  equip_type is error....equip_type:%d ", req.equip_type());
		m_pMaster->SendDataToClientEx(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_UNDRESS, &ret);
		return;
	}

	uint8_t byPos = (uint8_t)req.pos();
	if (!ValidEquipPos(byPos))
	{
		LogErrFmtPrint("[logic] PackagePart::EquipUnDress  ValidEquipPos false....byPos:%d ",byPos);
		ret.set_retcode(RET_EQUIP_EQUIP_POS_ERR);
		m_pMaster->SendDataToClientEx(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_UNDRESS, &ret);
		return;
	}

	ret.set_equip_type(req.equip_type());
	CEquip *pEquip = GetEquip(byPos, (EEquipType)req.equip_type());
	if (nullptr == pEquip)
	{
		ret.set_retcode(RET_EQUIP_POS_NOT_EXIT_EQUIP);
		m_pMaster->SendDataToClientEx(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_UNDRESS, &ret);
		return;
	}
	
	VEC_UINT16 vecEmptyGrid;
	vecEmptyGrid.clear();
	if (!GetEmptyGrid(EPackageLabel_all, vecEmptyGrid,1))
	{
		LogErrFmtPrint("[logic] PackagePart::EquipUnDress  GetEmptyGrid return false....");
		ret.set_retcode(RET_PACKAGE_SPACE_NOT_ENOUGH);
		m_pMaster->SendDataToClientEx(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_UNDRESS, &ret);
		return;
	}
	if (vecEmptyGrid.size() < 1)
	{
		//没有空格子 RET_PACKAGE_SPACE_NOT_ENOUGH
		ret.set_retcode(RET_PACKAGE_SPACE_NOT_ENOUGH);
		m_pMaster->SendDataToClientEx(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_UNDRESS, &ret);
		return;
	}
	
	uint16_t nDstIndex = vecEmptyGrid.at(0);
	if (!ValidLabelIndex(EPackageLabel_all, nDstIndex))
	{
		m_pMaster->SendDataToClientEx(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_UNDRESS, &ret);
		return;
	}

	//删除装备
	pEquip->SetIndex(0);
	pEquip->SetNum(0);
	UpdateEquipInfo(pEquip, (EEquipType)req.equip_type());
	SetEquipByIndex(byPos, nullptr, (EEquipType)req.equip_type());

	//装备回到包裹
	pEquip->SetIndex(nDstIndex);
	pEquip->SetNum(1);
	SetItemByIndex(nDstIndex, pEquip);

	ret.set_retcode(RET_SUCCESS);
	ret.set_pos(byPos);
	ret.set_dst_pos(nDstIndex);
	m_pMaster->SendDataToClientEx(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_UNDRESS, &ret);

	//LogDebugFmtPrint("[logic] PackagePart::EquipUnDress...byPos:%d , nDstIndex:%d itemid:%u ",byPos,nDstIndex,pEquip->GetItemID());

	CalcEquipAttr();
	
	if ((EEquipType)req.equip_type() == EEquipType_Equip)
	{
		VEC_PLAYER_EQUIP vecSync = m_vecPlayerEquip;
		SyncPlayerEquip(vecSync, true);
	}

	//if (!ValidEquipFacadePos(byPos))	return;
	
	if (EEquipPos_clothes == byPos)
	{
		if ((EEquipType)req.equip_type() == EEquipType_Equip)
		{
			m_equipFacade.clothesId = 0;
			m_equipFacade.runeYKId = 0;
			if (pEquip->GetHoly() > 0)
				RemoveRuneSkill(pEquip->GetHoly());
		}
		else if ((EEquipType)req.equip_type() == EEquipType_GodEquip)
			m_equipFacade.godClothesId = 0;
	}
	else if (EEquipPos_weapon == byPos)
	{
		if ((EEquipType)req.equip_type() == EEquipType_Equip)
		{
			m_equipFacade.weaponId = 0;
			m_equipFacade.runeDWId = 0;
			if (pEquip->GetHoly() > 0)
				RemoveRuneSkill(pEquip->GetHoly());
		}
		else if ((EEquipType)req.equip_type() == EEquipType_GodEquip)
			m_equipFacade.godWeaponId = 0;
	}
	else if (EEquipPos_wing == byPos)
	{
		m_equipFacade.wingId = 0;
	}
	FacadeChange((EEquipType)req.equip_type() == EEquipType_Equip);
}

void PackagePart::StatisticsEquip()
{
	SET_UINT32 lelSet;
	SET_UINT32 hLelSet;
	SET_UINT32 qulitySet;
	SET_UINT32 hQulitySet;
	for (uint8_t i = EEquipPos_none + 1; i <= EEquipPos_talisman; ++i)
	{
		CEquip *pEquip = GetEquip(i);
		if (nullptr == pEquip)
			return;
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pEquip->GetItemID());
		if (nullptr == pEquipCfg)
			return;

		lelSet.insert(pEquipCfg->wearLevel);
		qulitySet.insert(pEquipCfg->quality);
		if (pEquipCfg->wearLevel >= 50)
			hQulitySet.insert(pEquipCfg->quality);
		if (pEquipCfg->quality >= EQuality_purple)
			hLelSet.insert(pEquipCfg->wearLevel);
	}

	EquipDressEvent dressEvent;
	dressEvent.level = *lelSet.begin();
	dressEvent.quality = *qulitySet.begin();
	dressEvent.hQuality = hQulitySet.size() == 8 ? *hQulitySet.begin() : 0;
	dressEvent.hLevel = hLelSet.size() == 8 ? *hLelSet.begin() : 0;
	g_GetEvent()->FireExecute(EVENT_EQUIP_DRESS, m_pMaster->GetCid(), CREATURE_PLAYER, (EquipDressEvent*)&dressEvent, sizeof(EquipDressEvent));
}

bool PackagePart::RefineInLvl(uint16_t low, uint16_t up)
{
	for (uint8_t i = EEquipPos_none + 1; i <= EEquipPos_talisman; ++i)
	{
		CEquip *pEquip = GetEquip(i);
		if (pEquip && pEquip->GetRefineLev() >= low && pEquip->GetRefineLev() <= up)
			return true;
	}
	return false;
}

uint32_t PackagePart::GetTolRefineLvl()
{
	uint32_t totalLvl = 0;
	for (uint8_t i = EEquipPos_none + 1; i <= EEquipPos_talisman; ++i)
	{
		CEquip *pEquip = GetEquip(i);
		if (nullptr == pEquip)	continue;
		totalLvl += pEquip->GetRefineLev();
	}
	return totalLvl;
}

//更新装备
bool PackagePart::UpdateEquipInfo(PlayerEquipUpdateRet &update_ret)
{
	if (update_ret.update_size() > 0)
	{
		return m_pMaster->SendDataToClient(LOGIC_TO_CLIENT_PLAYER_EQUIP_UPDATE, &update_ret);
	}
	return false;
}
//更新装备
bool PackagePart::UpdateEquipInfo(CEquip *pEquip, EEquipType etype)
{
	if (nullptr == pEquip)
	{
		return false;
	}
	PlayerEquipUpdateRet ret;
	ret.set_equip_type(etype);
	ItemProtoInfo *protoItemInfo = ret.add_update();
	if (nullptr == protoItemInfo)
	{
		return false;
	}
	if (!SetUpdateItemInfo(pEquip, protoItemInfo))
	{
		return false;
	}
	
	return m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_UPDATE, &ret);
}

//更新槽位
bool PackagePart::UpdateEquipSlot(EquipSlot &slot)
{
	PlayerEquipSlotUpdateRet ret;
	EquipSlotProto *protoSlot = ret.add_update();
	if (nullptr != protoSlot)
	{
		SetEquipSlotInfo(slot, protoSlot);
		return m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PLAYER_EQUIP_SLOT_UPDATE, &ret);
	}
	return false;
}
//更新槽位
bool PackagePart::UpdateEquipSlot(PlayerEquipSlotUpdateRet &update_ret)
{
	if (update_ret.update_size() > 0)
	{
		return m_pMaster->SendDataToClient(LOGIC_TO_CLIENT_PLAYER_EQUIP_SLOT_UPDATE, &update_ret);
	}
	return false;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////// 装备养成  //////////////////////////////////////
//鉴定
void PackagePart::EquipIdentify(const char *data, uint32_t len)
{
	EquipIdentifyReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] EquipIdentifyReq parse failed....");
		return;
	}
	EquipIdentifyRsp rsp;
	rsp.set_retcode(RET_SUCCESS);

	CItemBase *pEquip = GetItemByIndex(req.index());
	if (nullptr == pEquip)
	{
		rsp.set_retcode(RET_EQUIP_EQUIP_NOT_EXIST);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_IDENTIFY, &rsp);
		return;
	}

	const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pEquip->GetItemID());
	if (nullptr == pEquipCfg)
	{
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_IDENTIFY, &rsp);
		return;
	}

	if (pEquip->Identify())
	{
		rsp.set_retcode(RET_EQUIP_ALREADY_IDENTIFY);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_IDENTIFY, &rsp);
		return;
	}

	const CItemBase* pCostItem = GetItemByType((int32_t)EItemSubType::EItemSubType_equip_identify);
	if (nullptr == pCostItem)
	{
		rsp.set_retcode(RET_PACKAGE_ITEM_NOT_EXITS);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_IDENTIFY, &rsp);
		return;
	}

	LIST_ITEM lstItem;
	lstItem.clear();
	SItem item;
	item.nItemID = pCostItem->GetItemID();
	item.nNum = 1;
	item.byBind = (int8_t)EBindState::EBindState_all;
	lstItem.push_back(item);
	SItemSourceParam sourceParam;
	sourceParam.source = S_Identify;
	RemoveItem(lstItem, sourceParam);
	pEquip->Identify(true);
	//UpdateEquipInfo((CEquip*)pEquip);
	//鉴定只能鉴定背包装备 所以更新背包信息
	PackageUpdateRet update;
	ItemProtoInfo *protoItem = update.add_item_list();
	SetUpdateItemInfo(pEquip, protoItem);
	UpdatePackageInfo(update);
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_IDENTIFY, &rsp);

	EquipIdentifyEvent identifyEvent;
	identifyEvent.equipId = pEquipCfg->id;
	identifyEvent.quality = pEquipCfg->quality;
	g_GetEvent()->FireExecute(EVENT_EQUIP_IDENTIFY, m_pMaster->GetCid(), m_pMaster->CreatureKind(), &identifyEvent, sizeof(EquipIdentifyEvent));
}

//勾选
void PackagePart::EquipSelect(const char *data, uint32_t len)
{
	EquipShowSelectReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] EquipShowSelectReq parse failed....");
		return;
	}

	m_equipFacade.showType = (EEquipType)req.equip_type();
	FacadeChange();

	EquipShowSelectRsp rsp;
	rsp.set_retcode(RET_SUCCESS);
	rsp.set_equip_type(req.equip_type());
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_SHOW_SELECT, &rsp);
}

//精炼
void PackagePart::EquipRefine(const char *data, uint32_t len)
{
	EquipForge_RefineReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] EquipForge_RefineReq parse failed....");
		return;
	}
	EquipForge_RefineRsp rsp;
	rsp.set_retcode(RET_SUCCESS);
	
	if (m_pMaster->GetAttr(C_LEVEL) < g_GetItemMgr()->GetOpenLel(FunctionUnlock_ID_TYPE_EQUIP_REFINE))
	{
		rsp.set_retcode(RET_LEVEL_LACK);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_REFINE, &rsp);
		return;
	}

	int32_t equip_type = req.equip_type();
	int32_t equip_pos = req.equip_pos();
	int32_t item_idx = req.item_idx();

	if (1 != equip_type && 2 != equip_type)
	{
		LogErrFmtPrint("[logic] PackagePart::EquipRefine 1 != equip_type && 2 != equip_type... error...equip_type:%d", equip_type);
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_REFINE, &rsp);
		return;
	}

	CItemBase *pEquip = nullptr;
	if (1 == equip_type)
	{
		if (!ValidLabelIndex(EPackageLabel_all, equip_pos))
		{
			rsp.set_retcode(RET_FAIL);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_REFINE, &rsp);
			return;
		}
		if (equip_pos == item_idx)
		{
			rsp.set_retcode(RET_PARMAR_ERROR);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_REFINE, &rsp);
			return;
		}
		pEquip = GetItemByIndex(equip_pos);
	}
	else
	{
		if (equip_pos <= EEquipPos_none || equip_pos >= EEquipPos_limit)
		{
			rsp.set_retcode(RET_FAIL);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_REFINE, &rsp);
			return;
		}
		pEquip = GetEquip(equip_pos);
	}

	if (nullptr == pEquip)
	{
		rsp.set_retcode(RET_EQUIP_EQUIP_NOT_EXIST);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_REFINE, &rsp);
		return;
	}

	const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pEquip->GetItemID());
	if (nullptr == pEquipCfg)
	{
		LogErrFmtPrint("[logic] PackagePart::EquipRefine...nullptr == pEquipCfg  itemid:%u ", pEquip->GetItemID());
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_REFINE, &rsp);
		return;
	}

	uint8_t refine_type = 0;	//精炼道具类型 0：无道具 1：增加成功率 2：保底等级
	int32_t addRefineRate = 0; 
	//int32_t luckyItemId = 0;	//幸运卷轴id
	if (item_idx > 0)
	{
		CItemBase *pItem = GetItemByIndex(item_idx);
		if (nullptr != pItem)
		{
			refine_type = 0;
			const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo((uint32_t)pItem->GetItemID());
			if (nullptr != pItemCfg)
			{
				if ((int32_t)EItemFuncType::EItemFuncType_RefineLucky != pItemCfg->functionType && (int32_t)EItemSubType::EItemSubType_refine_ensure != pItemCfg->subType)
				{
					LogErrFmtPrint("[logic] PackagePart::EquipRefine ItemItemCfgInfo *pItemCfg type error... itemId=%u...", pItem->GetItemID());
				}
				else
				{
					refine_type = ((int32_t)EItemFuncType::EItemFuncType_RefineLucky == pItemCfg->functionType) ? 1 : 2;
					if (refine_type == 1)
					{
						//luckyItemId = pItemCfg->id;
						const VEC_INT32 *pVecFuncParam = g_GetItemCfgMgr()->GetItemFuncParamCfg((uint32_t)pItemCfg->id);
						if (pVecFuncParam && pVecFuncParam->size() >= 1)
						{
							addRefineRate = pVecFuncParam->at(0);
						}
					}
				}
			}
			else
			{
				LogErrFmtPrint("[logic] PackagePart::EquipRefine ItemItemCfgInfo *pItemCfg = nullptr... itemId=%u...", pItem->GetItemID());
				rsp.set_retcode(RET_PARMAR_ERROR);
				m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_REFINE, &rsp);
				return;
			}
		}
		else
		{
			LogErrFmtPrint("[logic] PackagePart::EquipRefine CItemBase *pItem = nullptr... itemIndex=%d...", item_idx);
			rsp.set_retcode(RET_PACKAGE_LACK_REFINE_MATERIAL);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_REFINE, &rsp);
			return;
		}
	}

	uint32_t nRefineLev = pEquip->GetRefineLev();
	int32_t nextRefineLev = nRefineLev + 1;
	const EquipRefineCfgInfo *pCurRefineCfg = g_GetEquipCfgMgr()->GetRefineCfgInfo(pEquipCfg->position, nRefineLev, pEquipCfg->wearLevel);
	
	const EquipRefineCfgInfo *pRefineCfg = g_GetEquipCfgMgr()->GetRefineCfgInfo(pEquipCfg->position, nextRefineLev, pEquipCfg->wearLevel);
	if (nullptr == pRefineCfg)
	{
		rsp.set_retcode(RET_PACKAGE_REFINE_LEVEL_LIMIT);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_REFINE, &rsp);
		return;
	}

	int64_t nTotalGold = m_pMaster->GetAttr(C_GOLD);
	int64_t nNeedGold = pRefineCfg->gold;
	if (nTotalGold < nNeedGold)
	{
		rsp.set_retcode(RET_GOLD_LACK);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_REFINE, &rsp);
		return;
	}

	LIST_ITEM lstItem;
	lstItem.clear();
	int32_t stoneNum = 0;	//消耗精炼石
	uint32_t stoneItemId = 0;
	const VecEquipRefineItemCfg &vecRefineNeedCfg = pRefineCfg->vecEquipRefineItemCfg;
	VecEquipRefineItemCfg::const_iterator iter = vecRefineNeedCfg.begin();
	for (; iter != vecRefineNeedCfg.end(); ++iter)
	{
		const EquipRefineItemCfgInfo &refineCfg = (*iter);
		if (refineCfg.id > 0 && refineCfg.ratio > 0)
		{
			SItem item;
			item.nItemID = refineCfg.id;
			item.nNum = refineCfg.ratio;
			item.byBind = (int8_t)EBindState::EBindState_all;
			lstItem.push_back(item);
			stoneNum += item.nNum;
			stoneItemId = refineCfg.id;
		}
	}

	const ItemItemCfgInfo *pStoneItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(stoneItemId);
	if (nullptr == pStoneItemCfg)
	{
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_REFINE, &rsp);
		return;
	}

	if (!HasItem(lstItem))
	{
		rsp.set_retcode(RET_PACKAGE_LACK_REFINE_MATERIAL);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_REFINE, &rsp);
		return;
	}
	
	static uint32_t full_refine_rate = 100;
	bool result = false;
	if (((uint32_t)pRefineCfg->SuccessRate / 100 + addRefineRate) >= Random(full_refine_rate))
	{
		result = true;
	}

	if (result)
	{
		pEquip->SetRefineLev(nextRefineLev);
		//CalcEquipAttr();						//重新计算装备属性

		rsp.set_succuss(true);
	}
	else
	{
		rsp.set_succuss(false);
		if (pCurRefineCfg && pCurRefineCfg->lossLv == 0 && refine_type != 2)
			pEquip->SetRefineLev(nRefineLev-1);
	}

	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_REFINE, &rsp);

	//玩家穿戴装备精炼总等级
	int32_t totalRefuneLv = 0;
	if (equip_type == 1)	//背包
	{
		PackageUpdateRet update;
		ItemProtoInfo *protoItem = update.add_item_list();
		SetUpdateItemInfo(pEquip, protoItem);
		UpdatePackageInfo(update);
	}
	else if (equip_type == 2)	//装备
	{
		UpdateEquipInfo((CEquip*)pEquip);
		set<int32_t> levelSet;
		VEC_PLAYER_EQUIP::iterator iterEquip = m_vecPlayerEquip.begin();
		for (; iterEquip != m_vecPlayerEquip.end(); ++iterEquip)
		{
			CEquip *pDressEquip = (*iterEquip);
			if (nullptr != pDressEquip)
			{
				levelSet.insert(pDressEquip->GetRefineLev());
				totalRefuneLv += pDressEquip->GetRefineLev();
			}
		}

		if (levelSet.size() > 0)
		{
			RefineAllEvent refineAllEvent;			//全身装备槽位精炼达到X级
			refineAllEvent.level = *levelSet.begin();
			refineAllEvent.totalLvel = totalRefuneLv;
			g_GetEvent()->FireExecute(EVENT_EQUIP_REFINE_ALL, m_pMaster->GetCid(), m_pMaster->CreatureKind(), &refineAllEvent, sizeof(RefineAllEvent));
		}
		CalcEquipAttr();
	}

	//m_pMaster->AddAttr(C_GOLD, -1*(int64_t)nNeedGold, true);
	m_pMaster->AddSourceAttr(C_GOLD, -1 * (int64_t)nNeedGold, true, S_PACKAGE);
	SItemSourceParam sourceParam;
	sourceParam.source = S_Refine;
	RemoveItem(lstItem, sourceParam);
	RemoveItemByIndex(item_idx, 1, sourceParam);

	EquipRefineEvent refineEvent;				//精炼事件
	refineEvent.refinLevel = pEquip->GetRefineLev();
	refineEvent.slot = equip_pos;
	refineEvent.stoneNum = stoneNum;
	refineEvent.stoneItemId = stoneItemId;
	refineEvent.costLuckyItem = (refine_type == 1);
	refineEvent.itemId = pEquipCfg->id;	
	refineEvent.result = result;
	g_GetEvent()->FireExecute(EVENT_EQUIP_REFINE, m_pMaster->GetCid(), m_pMaster->CreatureKind(), &refineEvent, sizeof(EquipRefineEvent));

	if (!result)
	{
		EquipRefineFailEvent refineFailEvent;		//精炼失败事件
		g_GetEvent()->FireExecute(EVENT_EQUIP_REFINE_FAIL, m_pMaster->GetCid(), m_pMaster->CreatureKind(), &refineFailEvent, sizeof(EquipRefineFailEvent));
	}
	else if (equip_type == 2)
	{
		FacadeChange(true);
	}

	Player *pPlayer = dynamic_cast<Player*>(m_pMaster);
	if (nullptr == pPlayer)	return;

	uint64_t newGold = pPlayer->GetAttr(C_GOLD);
	uint64_t preGold = newGold + nNeedGold;
	pPlayer->RefineLog(pEquipCfg->id, nRefineLev, pEquip->GetRefineLev(), pEquipCfg->name, pStoneItemCfg->name, stoneNum, nNeedGold, preGold, newGold, result);
}

//强化
void PackagePart::EquipStren(const char *data, uint32_t len)
{
	EquipForge_StrenReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] EquipForge_StrenReq parse failed....");
		return;
	}

	EquipForge_StrenRsp rsp;
	rsp.set_retcode(RET_SUCCESS);

	if (m_pMaster->GetAttr(C_LEVEL) < g_GetItemMgr()->GetOpenLel(FunctionUnlock_ID_TYPE_EQUIP_STRENGER))
	{
		rsp.set_retcode(RET_LEVEL_LACK);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_STREN, &rsp);
		return;
	}

	int32_t stren_type = req.stren_type();
	int32_t equip_pos = req.equip_pos();
	if (stren_type != 1 && stren_type != 2) // 强化类型，1 强化一次，2 强化10次
	{
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_STREN, &rsp);
		return;
	}

	if (equip_pos <= EEquipPos_none || equip_pos >= EEquipPos_limit)
	{
		LogErrFmtPrint("[logic] PackagePart::EquipStren equip_pos error...", equip_pos);
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_STREN, &rsp);
		return;
	}

	const EquipStrengthenCfgData *pStrenCfg = g_GetEquipCfgMgr()->GetStrenthCfgInfo(m_pMaster->GetAttr(C_PROF), ConverPos(equip_pos));
	if (nullptr == pStrenCfg)
	{
		LogErrFmtPrint("[logic] PackagePart::EquipStren...nullptr == pStrenCfg pos:%d  ", equip_pos);
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_STREN, &rsp);
		return;
	}

	const EquipStrenCost *eCost = (m_pMaster->GetAttr(C_LEVEL) <= 60) ? &pStrenCfg->strenthCost_ver1 : &pStrenCfg->strenthCost_ver2;
	if (nullptr == eCost)
	{
		LogErrFmtPrint("[logic] PackagePart::EquipStren...nullptr == EquipStrenCost pos:%d  ", equip_pos);
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_STREN, &rsp);
		return;
	}

	LIST_ITEM lstItem;
	VEC_FLOAT vecPara;
	int32_t stoneNum = 0;
	int64_t nGoldNeed = 0;
	uint32_t nNextStrenLev = 0;
	int32_t nCount = (stren_type == 1) ? 1 : 10;
	EquipSlot &slot = m_vecEquipSlot[equip_pos];

	for (int32_t i = 1; i <= nCount; i++)
	{
		if (slot.m_nStrenLev >= m_pMaster->GetAttr(C_LEVEL))
		{
			rsp.set_retcode(RET_PACKAGE_STREN_LEVEL_LIMIT);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_STREN, &rsp);
			return;
		}
		nNextStrenLev = slot.m_nStrenLev + 1;

		//向下取整（装备品质*a1+装备穿戴等级*b1+（当前强化等级+1）*c1）
		//公式：a*x^2+b*x+c       a，b，c为填写的系数，x为强化等级。填写格式为：（a,b,c）
		SItem item;
		item.nItemID = eCost->itemId;
		item.nNum = (int32_t)floor(nNextStrenLev * nNextStrenLev * eCost->item_param_a + nNextStrenLev * eCost->item_param_b + eCost->item_param_c);
		item.byBind = (int8_t)EBindState::EBindState_all;
		if (item.nItemID > 0 && item.nNum > 0)
		{
			lstItem.push_back(item);
		}
		if (!HasItem(lstItem))
		{
			rsp.set_retcode(RET_PACKAGE_LACK_STREN_MATERIAL);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_STREN, &rsp);
			return;
		}
		stoneNum += item.nNum;
		
		//消耗的金币 向下取整（装备品质*a1 + 装备穿戴等级*b1 + （当前强化等级 + 1）*c1）
		//公式：a*x^2+b*x+c       a，b，c为填写的系数，x为强化等级。填写格式为：（a,b,c）	-->  (a*x)^3-b*x^2-c*x+d
		nGoldNeed = (int32_t)floor((pow(eCost->gold_param_a * nNextStrenLev, 3) - eCost->gold_param_b * pow(nNextStrenLev, 2) - eCost->gold_param_c * nNextStrenLev + eCost->gold_param_d) * eCost->gold_param_e);
		if (m_pMaster->GetAttr(C_GOLD) < nGoldNeed)
		{
			rsp.set_retcode(RET_GOLD_LACK);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_STREN, &rsp);
			return;
		}
		SItemSourceParam souceParam;
		souceParam.source = S_StrengenEquip;
		RemoveItem(lstItem, souceParam);
		//m_pMaster->AddAttr(C_GOLD, -nGoldNeed, true);
		m_pMaster->AddSourceAttr(C_GOLD, -nGoldNeed, true, S_PACKAGE);
		slot.m_nStrenLev = nNextStrenLev;
	}

	CalcEquipAttr();					//重新计算装备属性
	UpdateEquipSlot(slot);				//更新槽位

	EquipStrenEvent strenEvent;			//强化事件
	strenEvent.pos = (EEquipPos)equip_pos;
	strenEvent.strenLevel = slot.m_nStrenLev;
	strenEvent.slot = slot.m_nIndex;
	strenEvent.stoneNum = stoneNum;
	g_GetEvent()->FireExecute(EVENT_EQUP_STREN, m_pMaster->GetCid(), m_pMaster->CreatureKind(), &strenEvent, sizeof(EquipStrenEvent));

	set<int32_t> levelSet;
	for (uint8_t k = EEquipPos_none + 1; k <= EEquipPos_talisman; ++k)
	{
		EquipSlot &slot = m_vecEquipSlot[k];
			levelSet.insert(slot.m_nStrenLev);
	}
	if (levelSet.size() > 0)
	{
		StrenthAllEvent strenthAllEvent;			//全身装备槽位强化达到X级
		strenthAllEvent.level = *levelSet.begin();
		g_GetEvent()->FireExecute(EVENT_EQUP_STREN_ALL, m_pMaster->GetCid(), m_pMaster->CreatureKind(), &strenthAllEvent, sizeof(StrenthAllEvent));
	}
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_STREN, &rsp);
}

void PackagePart::GetStrenthLelMap(uint32_t nPlayerLev, SET_UINT32 &iset)
{
	ORDER_MAP_UINT32_SET_UINT32 mapLevSetPos;
	for (int32_t ite = EEquipPos_none + 1; ite <= EEquipPos_talisman; ++ite)
	{
		EquipSlot &slot = m_vecEquipSlot[ite];
		uint16_t nStrenLev = slot.m_nStrenLev;
		if (nStrenLev >= nPlayerLev)	continue;
		ORDER_MAP_UINT32_SET_UINT32::iterator iter = mapLevSetPos.find(nStrenLev);
		if (iter != mapLevSetPos.end())
		{
			SET_UINT32 &setPos = iter->second;
			setPos.insert(ite);
		}
		else
		{
			SET_UINT32 setPos;
			setPos.insert(ite);
			mapLevSetPos[nStrenLev] = setPos;
		}
	}
	if (mapLevSetPos.size() <= 0)	return;
	iset = mapLevSetPos.begin()->second;
}

//一键强化
void PackagePart::EquipOneKeyStren(const char *data, uint32_t len)
{
	//BEGIN_PROFILE("package use");
	//uint64_t curTick = Time::Now().UnixNano();
	EquipForge_RefineRsp rsp;
	int32_t retCode = RET_SUCCESS;
	rsp.set_retcode(retCode);

	if (m_pMaster->GetAttr(C_LEVEL) < g_GetItemMgr()->GetOpenLel(FunctionUnlock_ID_TYPE_EQUIP_STRENGER))
	{
		rsp.set_retcode(RET_LEVEL_LACK);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_STREN, &rsp);
		return;
	}

	uint32_t nPlayerLev = m_pMaster->GetAttr(C_LEVEL);
	int32_t nProf = m_pMaster->GetAttr(C_PROF);
	int32_t nBStoneNum = 0;
	int32_t nUBStoneNum = 0;
	int32_t curStoneNum = GetItemNum(EQUIP_STRENTH_STONE_ID, nBStoneNum, nUBStoneNum);
	int32_t costStoneNum = 0;
	int32_t curGold = m_pMaster->GetAttr(C_GOLD);
	int32_t costGold = 0;
	int32_t routeCount = 0;
	SET_INT32 setNeedUpdate;
	setNeedUpdate.clear();
	
	//BEGIN_PROFILE("EquipOneKeyStren--while");
	while (true)
	{
		SET_UINT32 setPos;
		setPos.clear();
		GetStrenthLelMap(nPlayerLev, setPos);
		if (setPos.size() <= 0)
		{
			retCode = RET_PACKAGE_NOT_CAN_STREN_EQUIP;
			break;
		}

		for (SET_UINT32::iterator iterPos = setPos.begin(); iterPos != setPos.end(); ++iterPos)
		{
			routeCount++;
			uint32_t nPos = (*iterPos);
			const EquipStrengthenCfgData *pStrenCfg = g_GetEquipCfgMgr()->GetStrenthCfgInfo(nProf, nPos);
			if (nullptr == pStrenCfg)
			{
				LogErrFmtPrint("[logic] PackagePart::EquipOneKeyStren...nullptr == pStrenCfg...  Prof:%d, pos:%d ", nProf, nPos);
				continue;
			}
			const EquipStrenCost *eCost = (nPlayerLev <= 60) ? &pStrenCfg->strenthCost_ver1 : &pStrenCfg->strenthCost_ver2;
			if (nullptr == eCost)
			{
				LogErrFmtPrint("[logic] PackagePart::EquipOneKeyStren...nullptr == eCost...  Prof:%d, pos:%d ", nProf, nPos);
				continue;
			}
			
			EquipSlot &slot = m_vecEquipSlot[nPos];
			uint32_t nNextStrenLev = slot.m_nStrenLev + 1;

			// 消耗物品 向下取整（装备品质*a1+装备穿戴等级*b1+（当前强化等级+1）*c1）
			int32_t nNum = (int32_t)floor(nNextStrenLev * nNextStrenLev * eCost->item_param_a + nNextStrenLev * eCost->item_param_b + eCost->item_param_c);
			if (nNum > curStoneNum)
			{
				retCode = RET_PACKAGE_LACK_STREN_MATERIAL;
				break;
			}

			int32_t nGoldNeed = (int32_t)floor((pow(eCost->gold_param_a * nNextStrenLev, 3) - eCost->gold_param_b * pow(nNextStrenLev, 2) - eCost->gold_param_c * nNextStrenLev + eCost->gold_param_d) * eCost->gold_param_e);
			if (nGoldNeed > curGold)
			{
				retCode = RET_GOLD_LACK;
				break;
			}

			curStoneNum -= nNum;
			costStoneNum += nNum;
			curGold -= nGoldNeed;
			costGold += nGoldNeed;
			setNeedUpdate.insert(nPos);
			slot.m_nStrenLev = nNextStrenLev;
		}
		if (RET_SUCCESS != retCode) //失败
		{
			break;
		}
	}
	//END_PROFILE();

	if ((routeCount == 0 || routeCount == 1) && retCode != RET_SUCCESS)
	{
		rsp.set_retcode(retCode);
	}
	//LogDebugFmtPrint("+++++++++++++++EquipOneKeyStren++++++++++++++++%lu", Time::Now().UnixNano() - curTick);
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_ONEKEY_STREN, &rsp);
	//LogDebugFmtPrint("+++++++++++++++EquipOneKeyStren++++++++++++++++%lu", Time::Now().UnixNano() - curTick);

	if (setNeedUpdate.size() <= 0)	
		return;

	if (costStoneNum > 0)
	{
		LIST_ITEM lstItem;
		lstItem.clear();
		SItem item;
		item.nItemID = EQUIP_STRENTH_STONE_ID;
		item.nNum = costStoneNum;
		item.byBind = (int8_t)EBindState::EBindState_all;
		lstItem.push_back(item);
		SItemSourceParam sourceParam;
		sourceParam.source = S_StrengenEquip;
		RemoveItem(lstItem, sourceParam);
	}
	if (costGold > 0)
	{
		//m_pMaster->AddAttr(C_GOLD, -costGold, true);
		m_pMaster->AddSourceAttr(C_GOLD, -costGold, true, S_PACKAGE);
	}

	//BEGIN_PROFILE("EquipOneKeyStren--CalcEquipAttr");
	CalcEquipAttr();
	//END_PROFILE();

	//BEGIN_PROFILE("EquipOneKeyStren--fireevent");
	SET_INT32::iterator iterUpdate = setNeedUpdate.begin();
	for (; iterUpdate != setNeedUpdate.end(); ++iterUpdate)
	{
		int32_t idx = (*iterUpdate);
		EquipSlot &slot = m_vecEquipSlot[idx];
		UpdateEquipSlot(slot);

		//强化事件
		EquipStrenEvent strenEvent;
		strenEvent.pos = (EEquipPos)idx;
		strenEvent.strenLevel = slot.m_nStrenLev;
		strenEvent.slot = slot.m_nIndex;
		g_GetEvent()->FireExecute(EVENT_EQUP_STREN, m_pMaster->GetCid(), m_pMaster->CreatureKind(), &strenEvent, sizeof(EquipStrenEvent));
	}

	//消耗强化石事件
	EquipStrenEvent costStoneEvent;
	costStoneEvent.stoneNum = costStoneNum;
	g_GetEvent()->FireExecute(EVENT_EQUP_STREN, m_pMaster->GetCid(), m_pMaster->CreatureKind(), &costStoneEvent, sizeof(EquipStrenEvent));

	set<int32_t> levelSet;
	for (uint8_t k = EEquipPos_none + 1; k <= EEquipPos_talisman; ++k)
	{
		EquipSlot &slot = m_vecEquipSlot[k];
		levelSet.insert(slot.m_nStrenLev);
	}
	if (levelSet.size() > 0)
	{
		//全身装备槽位强化达到X级
		StrenthAllEvent strenthAllEvent;			
		strenthAllEvent.level = *levelSet.begin();
		g_GetEvent()->FireExecute(EVENT_EQUP_STREN_ALL, m_pMaster->GetCid(), m_pMaster->CreatureKind(), &strenthAllEvent, sizeof(StrenthAllEvent));
	}
	//END_PROFILE();
	//END_PROFILE();
}

//镶嵌宝石
void PackagePart::StoneInlay(const char *data, uint32_t len)
{
	EquipForge_InlayReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] EquipForge_InlayReq parse failed...");
		return;
	}

	EquipForge_InlayRsp rsp;
	rsp.set_retcode(RET_SUCCESS);

	if (m_pMaster->GetAttr(C_LEVEL) < g_GetItemMgr()->GetOpenLel(FunctionUnlock_ID_TYPE_EQUIP_INLAY))
	{
		rsp.set_retcode(RET_LEVEL_LACK);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_INLAY, &rsp);
		return;
	}

	int32_t equip_type = req.equip_type();
	int32_t equip_pos = req.equip_pos();
	int32_t stone_idx = req.stone_idx();	//镶嵌的宝石所在背包的索引
	int32_t hole_idx = req.hole_idx();		//镶嵌孔索引(1-4)

	if (1 != equip_type && 2 != equip_type)
	{
		LogErrFmtPrint("[logic] PackagePart::StoneInlay 1 != equip_type && 2 != equip_type... error...equip_type:%d", equip_type);
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_INLAY, &rsp);
		return;
	}

	CItemBase *pEquip = nullptr;
	if (1 == equip_type)
	{
		if (!ValidLabelIndex(EPackageLabel_all, equip_pos))
		{
			rsp.set_retcode(RET_FAIL);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_INLAY, &rsp);
			return;
		}
		if (equip_pos == stone_idx)
		{
			rsp.set_retcode(RET_PARMAR_ERROR);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_INLAY, &rsp);
			return;
		}
		pEquip = GetItemByIndex(equip_pos);
	}
	else
	{
		if (equip_pos <= EEquipPos_none || equip_pos >= EEquipPos_limit)
		{
			rsp.set_retcode(RET_FAIL);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_INLAY, &rsp);
			return;
		}
		pEquip = GetEquip(equip_pos);
	}

	if (nullptr == pEquip)
	{
		rsp.set_retcode(RET_EQUIP_EQUIP_NOT_EXIST);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_INLAY, &rsp);
		return;
	}

	const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pEquip->GetItemID());
	if (nullptr == pEquipCfg)
	{
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_INLAY, &rsp);
		return;
	}

	if (hole_idx < 1 || hole_idx > MAX_EQUIP_HOLE_NUM)
	{
		LogErrFmtPrint("[logic] EquipForge_InlayReq hole_idx error...", hole_idx);
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_INLAY, &rsp);
		return;
	}

	//const EquipStrengthenCfgData *pStrenCfg = g_GetEquipCfgMgr()->GetStrenthCfgInfo(m_pMaster->GetAttr(C_PROF), pEquipCfg->position);
	const EquipStrengthenCfgData *pStrenCfg = g_GetEquipCfgMgr()->GetStrenthCfgInfo(pEquipCfg->profession, pEquipCfg->position);
	if (nullptr == pStrenCfg)
	{
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_INLAY, &rsp);
		return;
	}

	CItemBase *pInlayStone = GetItemByIndex(stone_idx);
	if (nullptr == pInlayStone)
	{
		rsp.set_retcode(RET_PACKAGE_INLAY_STONE_NOT_EXIST);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_INLAY, &rsp);
		return;
	}
	
	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pInlayStone->GetItemID());
	if (nullptr == pItemCfg)
	{
		LogErrFmtPrint("[logic] PackagePart::StoneInlay...nullptr == pItemCfg  itemid:%u ", pInlayStone->GetItemID());
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_INLAY, &rsp);
		return;
	}

	VEC_INT32::const_iterator iter = find(pStrenCfg->strenthCfg->vec_gemtype.begin(), pStrenCfg->strenthCfg->vec_gemtype.end(), pItemCfg->subType);
	if (iter == pStrenCfg->strenthCfg->vec_gemtype.end())
	{
		rsp.set_retcode(RET_PACKAGE_INLAY_STONE_TYPE_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_INLAY, &rsp);
		return;
	}

	if (pItemCfg->subType < (int32_t)EItemSubType::EItemSubType_stone_begin || pItemCfg->subType >(int32_t)EItemSubType::EItemSubType_stone_end)
	{
		LogErrFmtPrint("[logic] PackagePart::StoneInlay...item is not stone..  itemid:%u,subtype:%d ", pInlayStone->GetItemID(), pItemCfg->subType);
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_INLAY, &rsp);
		return;
	}

	VEC_UINT32 &inlayVec = *(pEquip->GetInlay());
	if (inlayVec.at(hole_idx - 1) > 0)
	{
		rsp.set_retcode(RET_PACKAGE_ALREADY_INLAY);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_INLAY, &rsp);
		return;
	}

	
	pInlayStone->AddNum(-1);									//镶嵌成功，先从背包扣除宝石
	PackageUpdateRet update;									//更新背包
	ItemProtoInfo *protoItem = update.add_item_list();
	if (nullptr != protoItem)	SetUpdateItemInfo(pInlayStone, protoItem);
		
	if (pInlayStone->GetNum() == 0)								//如果数量为0 该位置设置为空
	{
		SetItemByIndex(pInlayStone->GetIndex(), nullptr);		//删除物品
		g_GetItemMgr()->FreeItemObj(pInlayStone);				//回收物品
	}
	
	inlayVec[hole_idx - 1] = pItemCfg->id;						//镶嵌宝石
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_INLAY, &rsp);

	if (equip_type == 1)	//背包
	{
		ItemProtoInfo *protoEquipItem = update.add_item_list();
		SetUpdateItemInfo(pEquip, protoEquipItem);
	}
	else if (equip_type == 2)	//装备
	{
		UpdateEquipInfo((CEquip*)pEquip);
		CalcEquipAttr();										//重新计算属性
	}
	UpdatePackageInfo(update);
	
	Player *pPlayer = dynamic_cast<Player*>(m_pMaster);
	if (nullptr != pPlayer)
		pPlayer->InlayLog(pEquipCfg->id, pEquipCfg->name, pItemCfg->name);

	uint32_t totalLel = 0;
	SET_UINT32 lelSet;
	bool doBreak = false;	//是否中断计算平均等级
	for (uint8_t i = EEquipPos_none + 1; i <= EEquipPos_talisman; ++i)
	{
		CEquip *pEquip = GetEquip(i);
		if (nullptr != pEquip)
		{
			VEC_UINT32 &inlayVec = *(pEquip->GetInlay());
			for (VEC_UINT32::iterator iterInlay = inlayVec.begin(); iterInlay != inlayVec.end(); ++iterInlay)
			{
				uint32_t nStoneID = (*iterInlay);
				if (nStoneID == 0)
				{
					doBreak = true;
					continue;
				}
				const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(nStoneID);
				if (nullptr == pItemCfg)
				{
					doBreak = true;
					continue;
				}
				totalLel += pItemCfg->itemLevel;
				lelSet.insert(pItemCfg->itemLevel);
			}
		}
		else
			doBreak = true;
	}

	//七日目标活动
	OperateWelfarePart *pWelfarePart = dynamic_cast<OperateWelfarePart*>(m_pMaster->GetPart(PART_WELFARE));
	if (nullptr != pWelfarePart && pWelfarePart->Goals7DaysNeedStatics())
	{
		pWelfarePart->Goals7DaysUpdate(Goals7DayType_Stone, Goals7DayUpdateType_Total, Goals7DaySubType_StoneTotalLel, totalLel);
		pWelfarePart->Goals7DaysUpdate(Goals7DayType_Stone, Goals7DayUpdateType_Total, Goals7DaySubType_StoneSingleLel, pItemCfg->itemLevel);
		if (!doBreak)
			pWelfarePart->Goals7DaysUpdate(Goals7DayType_Stone, Goals7DayUpdateType_Total, Goals7DaySubType_StoneAverageLel, *lelSet.begin());
	}

	StoneInlayEvent inlayEvent;									//镶嵌宝石事件
	inlayEvent.pos = equip_pos;
	inlayEvent.stone_itemId = pItemCfg->id;
	inlayEvent.stone_level = pItemCfg->itemLevel;
	inlayEvent.total_level = totalLel;
	inlayEvent.ave_stone_level = (doBreak ? 0 : *lelSet.begin());
	g_GetEvent()->FireExecute(EVENT_STONE_INLAY, m_pMaster->GetCid(), m_pMaster->CreatureKind(), &inlayEvent, sizeof(StoneInlayEvent));
}

//取下宝石
void PackagePart::StoneTakeoff(const char *data, uint32_t len)
{
	EquipForge_TakeOffReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] EquipForge_TakeOffReq parse failed...");
		return;
	}

	EquipForge_TakeOffRsp rsp;
	rsp.set_retcode(RET_SUCCESS);

	int32_t equip_type = req.equip_type();
	int32_t equip_pos = req.equip_pos();  
	int32_t hole_idx = req.hole_idx();      //取下宝石所在装备孔的索引(1-6)

	if (1 != equip_type && 2 != equip_type)
	{
		LogErrFmtPrint("[logic] PackagePart::StoneTakeoff 1 != equip_type && 2 != equip_type... error...equip_type:%d", equip_type);
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_TAKEOFF, &rsp);
		return;
	}

	CItemBase *pEquip = nullptr;
	if (1 == equip_type)
	{
		if (!ValidLabelIndex(EPackageLabel_all, equip_pos))
		{
			rsp.set_retcode(RET_FAIL);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_TAKEOFF, &rsp);
			return;
		}
		pEquip = GetItemByIndex(equip_pos);
	}
	else
	{
		if (equip_pos <= EEquipPos_none || equip_pos >= EEquipPos_limit)
		{
			rsp.set_retcode(RET_FAIL);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_TAKEOFF, &rsp);
			return;
		}
		pEquip = GetEquip(equip_pos);
	}

	if (nullptr == pEquip)
	{
		rsp.set_retcode(RET_EQUIP_EQUIP_NOT_EXIST);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_TAKEOFF, &rsp);
		return;
	}

	if (hole_idx < 1 || hole_idx > MAX_EQUIP_HOLE_NUM)
	{
		LogErrFmtPrint("[logic] StoneTakeoff hole_idx error...", hole_idx);
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_TAKEOFF, &rsp);
		return;
	}

	VEC_UINT32 &inlayVec = *(pEquip->GetInlay());
	if (inlayVec.at(hole_idx - 1) <= 0)
	{
		rsp.set_retcode(RET_PACKAGE_NOT_INLAY);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_TAKEOFF, &rsp);
		return;
	}
	
	uint32_t nStoneID = inlayVec.at(hole_idx - 1);
	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(nStoneID);
	if (nullptr == pItemCfg)
	{
		LogErrFmtPrint("[logic] PackagePart::StoneTakeoff....nullptr == pItemCfg.. nStoneID:%u ", nStoneID);
		rsp.set_retcode(RET_PACKAGE_INLAY_HOLY_NOT_EXIST);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_TAKEOFF, &rsp);
		return;
	}

	LIST_ITEM lstItem;
	SItem item;
	item.nItemID = nStoneID;
	item.nNum = 1;
	lstItem.push_back(item);
	SItemSourceParam sourceParam;
	if (!AddItem(lstItem, sourceParam, false))
	{
		rsp.set_retcode(RET_PACKAGE_SPACE_NOT_ENOUGH);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_TAKEOFF, &rsp);
		return;
	}
	
	if (m_setIdxRecord.size() != 1)
	{
		LogErrFmtPrint("[logic] PackagePart::RuneDown...rune m_setIdxRecord.size() != 1 ");
		rsp.set_retcode(RET_PACKAGE_SPACE_NOT_ENOUGH);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_TAKEOFF, &rsp);
		return;
	}

	inlayVec[hole_idx - 1] = 0;

	if (equip_type == 1)	//背包
	{
		PackageUpdateRet update;
		ItemProtoInfo *protoItem = update.add_item_list();
		SetUpdateItemInfo(pEquip, protoItem);
		UpdatePackageInfo(update);
	}
	else if (equip_type == 2)	//装备
	{
		UpdateEquipInfo((CEquip*)pEquip);
		CalcEquipAttr();
	}

	rsp.set_item_idx(*(m_setIdxRecord.begin()));
	rsp.set_item_id(nStoneID);
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_TAKEOFF, &rsp);
}

//材料合成
void PackagePart::MaterialCompose(const char *data, uint32_t len)
{
	EquipForge_ComposeMaterialReq req;
	if (!req.ParseFromArray(data,len))
	{
		LogErrFmtPrint("[logic] EquipForge_ComposeMaterialReq parse failed....");
		return;
	}
	int32_t nDstItemID = req.dst_item_id();
	int32_t nDstNum = req.dst_num();
	if (nDstNum <= 0 || nDstItemID <=0)
	{
		return;
	}
	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(nDstItemID);
	if (nullptr == pItemCfg)
	{
		LogErrFmtPrint("[logic] PackagePart::MaterialCompose  nullptr == pItemCfg...itemid:%u ",nDstItemID);
		return;
	}
	const ComposeComposeCfgInfo *pComposeCfg = g_GetComposeComposeCfgTable()->GetComposeComposeCfgInfo(nDstItemID);
	if (nullptr == pComposeCfg)
	{
		LogErrFmtPrint("[logic] PackagePart::MaterialCompose  nullptr == pComposeCfg...itemid:%u ", nDstItemID);
		return;
	}
	const VecComposeComposeItemCfg vecComposeCfg = pComposeCfg->vecComposeComposeItemCfg;
	LIST_ITEM lstRemoveItem;
	lstRemoveItem.clear();
	MAP_UINT32_UINT32 mapParam;
	mapParam.clear();
	VecComposeComposeItemCfg::const_iterator iterCompose = vecComposeCfg.begin();
	for (; iterCompose != vecComposeCfg.end(); ++iterCompose)
	{
		const ComposeComposeItemCfgInfo &info = (*iterCompose);
		if (info.id <= 0 || info.num <= 0)
		{
			continue;
		}
		SItem item;
		item.nItemID = info.id;
		item.nNum = info.num * nDstNum;
		lstRemoveItem.push_back(item);
	}
	EquipForge_ComposeMaterialRsp rsp;
	rsp.set_retcode(RET_FAIL);
	if (!HasItem(lstRemoveItem))
	{
		//材料不够 RET_PACKAGE_COMPOSE_MATERIAL_LACK
		rsp.set_retcode(RET_PACKAGE_COMPOSE_MATERIAL_LACK);
	}
	else
	{
		/*int8_t byDstBind = g_GetItemMgr()->BindStateByAdd(nDstItemID);
		if (-1 == byDstBind)
		{
			LogErrFmtPrint("[logic] PackagePart::MaterialCompose....dst item bind state error....cid:%lu, itemid:%u, bybind:%d ", m_pMaster->GetCid(),nDstItemID,byDstBind);
			return;
		}*/
		LIST_ITEM lstAddItem;
		SItem item;
		item.nItemID = nDstItemID;
		item.nNum = nDstNum;
		//item.byBind = byDstBind;
		lstAddItem.push_back(item);
		if (!CanAddItem(lstAddItem))
		{
			rsp.set_retcode(RET_PACKAGE_SPACE_NOT_ENOUGH);
		}
		else
		{
			SItemSourceParam sourceParam;
			sourceParam.source = S_MaterialCompose;
			RemoveItem(lstRemoveItem, sourceParam);
			AddItem(lstAddItem, sourceParam);
			rsp.set_retcode(RET_SUCCESS);

			ComposeEvent composeEvent;//合成事件
			composeEvent.type = pComposeCfg->composeType;
			composeEvent.itemId = nDstItemID;
			composeEvent.num = nDstNum;
			g_GetEvent()->FireExecute(EVENT_COMPOSE, m_pMaster->GetCid(), m_pMaster->CreatureKind(), &composeEvent, sizeof(ComposeEvent));
		}

	}
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_COMPOSE_MATERIAL, &rsp);
}
//宝石合成
void PackagePart::StoneCompose(const char *data, uint32_t len)
{
	EquipForge_ComposeReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] EquipForge_ComposeReq parse failed...");
		return;
	}

	EquipForge_ComposeRsp rsp;
	rsp.set_retcode(RET_FAIL);

	int32_t idx = req.idx();		//待合成的宝石所在背包的索引
	int32_t type = req.type();		//合成类型 1 合成一个，2 合成所有
	int32_t composeid = req.compose_id();
	if (1 != type && 2 != type)
	{
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_COMPOSE, &rsp);
		return;
	}
	
	CItemBase *pStone = GetItemByIndex(idx);
	if (nullptr == pStone)
	{
		rsp.set_retcode(RET_PACKAGE_ITEM_NOT_EXITS);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_COMPOSE, &rsp);
		return;
	}

	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pStone->GetItemID());
	if (nullptr == pItemCfg)
	{
		LogErrFmtPrint("[logic] PackagePart::StoneCompose.. nullptr == pItemCfg  itemid:%u ", pStone->GetItemID());
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_COMPOSE, &rsp);
		return;
	}

	const ItemItemCfgInfo *pComposeItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(composeid);
	if (nullptr == pComposeItemCfg)
	{
		LogErrFmtPrint("[logic] PackagePart::StoneCompose..nullptr == pComposeItemCfg  itemid:%u ", composeid);
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_COMPOSE, &rsp);
		return;
	}

	const ComposeComposeCfgInfo *pComposeCfg = g_GetComposeComposeCfgTable()->GetComposeComposeCfgInfo(composeid);
	if (nullptr == pComposeCfg)
	{
		LogErrFmtPrint("[logic] PackagePart::StoneCompose.. nullptr == pComposeCfg  itemid:%u ", composeid);
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_COMPOSE, &rsp);
		return;
	}

	int32_t composeCount = 0;	//合成数量
	LIST_ITEM rmvItem;
	rmvItem.clear();
	if (1 == type)	//合成一个
	{
		composeCount = 1;
		VecComposeComposeItemCfg::const_iterator iterVec = pComposeCfg->vecComposeComposeItemCfg.begin();
		for (; iterVec != pComposeCfg->vecComposeComposeItemCfg.end(); ++iterVec)
		{
			const ComposeComposeItemCfgInfo &info = (*iterVec);
			if (info.id > 0 && info.num > 0)
			{
				SItem item;
				item.nItemID = info.id;
				item.nNum = info.num;
				item.byBind = (int8_t)EBindState::EBindState_all;
				rmvItem.push_back(item);
			}
		}
	}
	else if(2 == type)	//合成所有
	{
		composeCount = 0;
		int32_t tempCount = 0;
		int32_t nBStoneNum = 0;
		int32_t nUBStoneNum = 0;
		for (VecComposeComposeItemCfg::const_iterator iterVec = pComposeCfg->vecComposeComposeItemCfg.begin(); iterVec != pComposeCfg->vecComposeComposeItemCfg.end(); ++iterVec)
		{
			const ComposeComposeItemCfgInfo &info = (*iterVec);
			if (info.id > 0 && info.num > 0)
			{
				int32_t nHasNum = GetItemNum(info.id, nBStoneNum, nUBStoneNum);
				tempCount = nHasNum / info.num;
				if (tempCount <= 0)
				{
					rsp.set_retcode(RET_PACKAGE_COMPOSE_MATERIAL_LACK);
					m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_COMPOSE, &rsp);
					return;
				}
				if (composeCount <= 0)
				{
					composeCount = tempCount;
					continue;
				}
				composeCount = tempCount <= composeCount ? tempCount : composeCount;
			}
		}
		if (composeCount <= 0)
		{
			rsp.set_retcode(RET_FAIL);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_COMPOSE, &rsp);
			return;
		}
		for (VecComposeComposeItemCfg::const_iterator iterVec = pComposeCfg->vecComposeComposeItemCfg.begin(); iterVec != pComposeCfg->vecComposeComposeItemCfg.end(); ++iterVec)
		{
			const ComposeComposeItemCfgInfo &info = (*iterVec);
			if (info.id > 0 && info.num > 0)
			{
				SItem item;
				item.nItemID = info.id;
				item.nNum = info.num * composeCount;
				item.byBind = (int8_t)EBindState::EBindState_all;
				rmvItem.push_back(item);
			}
		}
	}
	
	if (!HasItem(rmvItem))
	{
		rsp.set_retcode(RET_PACKAGE_COMPOSE_MATERIAL_LACK);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_COMPOSE, &rsp);
		return;
	}

	LIST_ITEM lstItem;
	SItem item;
	item.nItemID = composeid;
	item.nNum = composeCount;
	lstItem.push_back(item);

	SItemSourceParam sourceParam;
	sourceParam.source = S_StoneCompose;
	if (!AddItem(lstItem, sourceParam))
	{
		//背包空间不够
		rsp.set_retcode(RET_PACKAGE_SPACE_NOT_ENOUGH);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_COMPOSE, &rsp);
		return;
	}

	RemoveItem(rmvItem, sourceParam);

	rsp.set_retcode(RET_SUCCESS);
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_COMPOSE, &rsp);

	ComposeEvent composeEvent;//合成事件
	composeEvent.type = pComposeCfg->composeType;
	composeEvent.itemId = composeid;
	composeEvent.num = composeCount;
	g_GetEvent()->FireExecute(EVENT_COMPOSE, m_pMaster->GetCid(), m_pMaster->CreatureKind(), &composeEvent, sizeof(ComposeEvent));
}

//分解
void PackagePart::EquipDecompose(const char *data, uint32_t len)
{
	EquipForge_DecomposeReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] EquipForge_DecomposeReq parse failed...");
		return;
	}

	EquipForge_DecomposeRsp rsp;
	rsp.set_retcode(RET_SUCCESS);

	if (m_pMaster->GetAttr(C_LEVEL) < g_GetItemMgr()->GetOpenLel(FunctionUnlock_ID_TYPE_EQUIP_RESOLVE))
	{
		rsp.set_retcode(RET_LEVEL_LACK);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_DECOMPOSE, &rsp);
		return;
	}

	CItemBase *pEquip = GetItemByIndex(req.index());
	if (nullptr == pEquip)
	{
		rsp.set_retcode(RET_EQUIP_EQUIP_NOT_EXIST);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_DECOMPOSE, &rsp);
		return;
	}

	const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pEquip->GetItemID());
	if (nullptr == pEquipCfg)
	{
		//装备不存在
		LogErrFmtPrint("[logic] PackagePart::EquipDecompose...nullptr == pEquipCfg  itemid:%u ", pEquip->GetItemID());
		rsp.set_retcode(RET_EQUIP_EQUIP_NOT_EXIST);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_DECOMPOSE, &rsp);
		return;
	}

	if (pEquipCfg->decomposeID <= 0) 
	{
		rsp.set_retcode(RET_PACKAGE_DECOMPOSE_QUALITY_LIMIT);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_DECOMPOSE, &rsp);
		return;
	}

	
	if (pEquipCfg->decomposeID > 0 && pEquipCfg->decompose > 0)
	{
		LIST_ITEM lstItem;
		lstItem.clear();

		//分解资源
		SItem item;
		item.nItemID = pEquipCfg->decomposeID;
		item.nNum = pEquipCfg->decompose;
		lstItem.push_back(item);

		//镶嵌宝石
		VEC_UINT32 *pInlay = pEquip->GetInlay();
		if (pInlay && pInlay->size() > 0)
		{
			for (VEC_UINT32::iterator iterInlay = pInlay->begin(); iterInlay != pInlay->end(); ++iterInlay)
			{
				uint32_t nStoneID = (*iterInlay);
				if (nStoneID == 0)		continue;
				SItem item;
				item.nItemID = nStoneID;
				item.nNum = 1;
				lstItem.push_back(item);
			}
		}

		//符文
		if (pEquip->GetHoly() > 0)
		{
			SItem item;
			item.nItemID = pEquip->GetHoly();
			item.nNum = 1;
			lstItem.push_back(item);
		}
		SItemSourceParam sourceParam;
		sourceParam.source = S_DEPUTY;
		if (!AddItem(lstItem, sourceParam))
		{
			rsp.set_retcode(RET_PACKAGE_SPACE_NOT_ENOUGH);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_DECOMPOSE, &rsp);
			return;
		}
	}

	EquipRecastEvent recasteEvent;
	recasteEvent.itemId = pEquip->GetItemID();
	g_GetEvent()->FireExecute(EVENT_EQUIP_RECAST, m_pMaster->GetCid(), m_pMaster->CreatureKind(), &recasteEvent, sizeof(EquipRecastEvent));

	SItemSourceParam sourceParam;
	sourceParam.source = S_Decompose;
	RemoveItemByIndex(req.index(), 1, sourceParam);
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_EQUIP_DECOMPOSE, &rsp);
}

//印刻符文
void PackagePart::RuneUp(const char *data, uint32_t len)
{
	EquipRune_UpOperateReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] EquipRune_UpOperateReq parse failed...");
		return;
	}

	EquipRune_UpOperateRsp rsp;
	rsp.set_retcode(RET_SUCCESS);

	if (m_pMaster->GetAttr(C_LEVEL) < g_GetItemMgr()->GetOpenLel(FunctionUnlock_ID_TYPE_EQUIP_RUNE))
	{
		rsp.set_retcode(RET_LEVEL_LACK);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_UP_OPERATE, &rsp);
		return;
	}

	int32_t equip_type = req.equip_type();
	int32_t equip_pos = req.equip_pos();

	if (1 != equip_type && 2 != equip_type)
	{
		LogErrFmtPrint("[logic] PackagePart::RuneUp 1 != equip_type && 2 != equip_type... error...equip_type:%d", equip_type);
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_UP_OPERATE, &rsp);
		return;
	}

	CItemBase *pEquip = nullptr;
	if (1 == equip_type)
	{
		if (!ValidLabelIndex(EPackageLabel_all, equip_pos))
		{
			rsp.set_retcode(RET_FAIL);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_UP_OPERATE, &rsp);
			return;
		}
		if (equip_pos == (int32_t)req.item_idx())
		{
			rsp.set_retcode(RET_PARMAR_ERROR);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_UP_OPERATE, &rsp);
			return;
		}
		pEquip = GetItemByIndex(equip_pos);
	}
	else
	{
		if (equip_pos <= EEquipPos_none || equip_pos >= EEquipPos_limit)
		{
			rsp.set_retcode(RET_FAIL);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_UP_OPERATE, &rsp);
			return;
		}
		pEquip = GetEquip(equip_pos);
	}

	if (nullptr == pEquip)
	{
		rsp.set_retcode(RET_EQUIP_EQUIP_NOT_EXIST);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_UP_OPERATE, &rsp);
		return;
	}

	const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pEquip->GetItemID());
	if (nullptr == pEquipCfg)
	{
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_UP_OPERATE, &rsp);
		return;
	}

	CItemBase *pItem = GetItemByIndex(req.item_idx());
	if (nullptr == pItem)
	{
		rsp.set_retcode(RET_PACKAGE_ITEM_NOT_EXITS);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_UP_OPERATE, &rsp);
		return;
	}

	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItem->GetItemID());
	if (nullptr == pItemCfg)
	{
		LogErrFmtPrint("[logic] PackagePart::RuneUp...nullptr == pItemCfg  itemid:%u ", pItem->GetItemID());
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_UP_OPERATE, &rsp);
		return;
	}

	if (pItemCfg->subType < (int32_t)EItemSubType::EItemSubType_dy_rune_begin || pItemCfg->subType >(int32_t)EItemSubType::EItemSubType_yk_rune_end)
	{
		//非符文(神印石)
		LogErrFmtPrint("[logic] PackagePart::RuneUp...item is not rune..  itemid:%u,subtype:%d ", pItem->GetItemID(), pItemCfg->subType);
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_UP_OPERATE, &rsp);
		return;
	}

	uint32_t runeItemId = pItem->GetItemID();
	EItemRuneType runeType = TuneType((EItemSubType)pItemCfg->subType);
	if (EItemRuneType_DW != runeType && EItemRuneType_YK != runeType)
	{
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_UP_OPERATE, &rsp);
		return;
	}

	if (runeItemId == pEquip->GetHoly())
	{
		rsp.set_retcode(RET_PACKAGE_HAS_SAME_RUNE);		//相同的符文ID 不能替换
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_UP_OPERATE, &rsp);
		return;
	}

	SItemSourceParam sourceParam;
	sourceParam.source = S_RuneUp;
	if (!RemoveItemByIndex(req.item_idx(), 1, sourceParam))
	{
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_UP_OPERATE, &rsp);
		return;
	}
	
	if (pEquip->GetHoly() > 0)
	{
		LIST_ITEM lstItem;
		SItem item;
		item.nItemID = pEquip->GetHoly();
		item.nNum = 1;
		lstItem.push_back(item);
		SItemSourceParam sourceParam;
		sourceParam.source = S_NONE;
		AddItem(lstItem, sourceParam, false);

		//删除替换之前的符文技能
		if (equip_type == 2)	//穿戴装备
			RemoveRuneSkill(pEquip->GetHoly());

		if (m_setIdxRecord.size() != 1)
		{
			LogErrFmtPrint("[logic] PackagePart::RuneUp...rune m_setIdxRecord.size() != 1 ");
			rsp.set_retcode(RET_PACKAGE_SPACE_NOT_ENOUGH);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_UP_OPERATE, &rsp);
			return;
		}
		rsp.set_item_idx(*(m_setIdxRecord.begin()));
		rsp.set_item_id(pEquip->GetHoly());
	}
	
	pEquip->SetHoly(runeItemId);
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_UP_OPERATE, &rsp);


	if (equip_type == 1)	//背包
	{
		PackageUpdateRet update;
		ItemProtoInfo *protoItem = update.add_item_list();
		SetUpdateItemInfo(pEquip, protoItem);
		UpdatePackageInfo(update);
	}
	else if (equip_type == 2)	//装备
	{
		UpdateEquipInfo((CEquip*)pEquip);

		if (EItemRuneType_DW == runeType)
			m_equipFacade.runeDWId = runeItemId;
		else if (EItemRuneType_YK == runeType)
			m_equipFacade.runeYKId = runeItemId;
		FacadeChange();
		//增加镶嵌符文对应的技能
		AddRuneSkill(pItemCfg);
	}
	//CalcEquipAttr();

	RuneInlayEvent runeEvent;
	runeEvent.type = runeType;
	g_GetEvent()->FireExecute(EVENT_RUNE_INLAY, m_pMaster->GetCid(), m_pMaster->CreatureKind(), &runeEvent, sizeof(runeEvent));

	Player *pPlayer = dynamic_cast<Player*>(m_pMaster);
	if (nullptr == pPlayer)	return;
	pPlayer->RuneLog(pEquipCfg->id, pEquipCfg->name, pItemCfg->name);
}

//摘除符文
void PackagePart::RuneDown(const char *data, uint32_t len)
{
	EquipRune_DownOperateReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] EquipRune_DownOperateReq parse failed...");
		return;
	}

	EquipRune_DownOperateRsp rsp;
	rsp.set_retcode(RET_SUCCESS);

	int32_t equip_type = req.equip_type();
	int32_t equip_pos = req.equip_pos();

	if (1 != equip_type && 2 != equip_type)
	{
		LogErrFmtPrint("[logic] PackagePart::RuneDown 1 != equip_type && 2 != equip_type... error...equip_type:%d", equip_type);
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_UP_OPERATE, &rsp);
		return;
	}

	CItemBase *pEquip = nullptr;
	if (1 == equip_type)
	{
		if (!ValidLabelIndex(EPackageLabel_all, equip_pos))
		{
			rsp.set_retcode(RET_FAIL);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_DOWN_OPERATE, &rsp);
			return;
		}
		pEquip = GetItemByIndex(equip_pos);
	}
	else
	{
		if (equip_pos <= EEquipPos_none || equip_pos >= EEquipPos_limit)
		{
			rsp.set_retcode(RET_FAIL);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_DOWN_OPERATE, &rsp);
			return;
		}
		pEquip = GetEquip(equip_pos);
	}

	if (nullptr == pEquip)
	{
		rsp.set_retcode(RET_EQUIP_EQUIP_NOT_EXIST);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_DOWN_OPERATE, &rsp);
		return;
	}

	if (pEquip->GetHoly() <= 0)
	{
		rsp.set_retcode(RET_PACKAGE_ITEM_NOT_EXITS);		//当前没有该符文
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_DOWN_OPERATE, &rsp);
		return;
	}

	LIST_ITEM lstItem;
	SItem item;
	//item.nItemID = m_nRuneItemId[runeType];
	item.nItemID = pEquip->GetHoly();
	item.nNum = 1;
	lstItem.push_back(item);
	SItemSourceParam sourceParam;
	if (!AddItem(lstItem, sourceParam, false))
	{
		rsp.set_retcode(RET_PACKAGE_SPACE_NOT_ENOUGH);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_DOWN_OPERATE, &rsp);
		return;
	}

	if (m_setIdxRecord.size() != 1)
	{
		LogErrFmtPrint("[logic] PackagePart::RuneDown.. m_setIdxRecord.size() != 1 ");
		rsp.set_retcode(RET_PACKAGE_SPACE_NOT_ENOUGH);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_DOWN_OPERATE, &rsp);
		return;
	}

	rsp.set_item_idx(*(m_setIdxRecord.begin()));
	rsp.set_item_id(pEquip->GetHoly());

	//删除符文技能
	if (equip_type == 2)	//穿戴装备
		RemoveRuneSkill(pEquip->GetHoly());
	pEquip->SetHoly(0);
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_DOWN_OPERATE, &rsp);

	if (equip_type == 1)	//背包
	{
		PackageUpdateRet update;
		ItemProtoInfo *protoItem = update.add_item_list();
		SetUpdateItemInfo(pEquip, protoItem);
		UpdatePackageInfo(update);
	}
	else if (equip_type == 2)	//装备
	{
		UpdateEquipInfo((CEquip*)pEquip);

		GetRuneItemId(m_equipFacade.runeDWId, m_equipFacade.runeYKId);
		FacadeChange();
	}
	//CalcEquipAttr();
}

EItemRuneType PackagePart::TuneType(EItemSubType type)
{
	if (type >= EItemSubType::EItemSubType_dy_rune_begin && type <= EItemSubType::EItemSubType_dy_rune_end)
	{
		return EItemRuneType_DW;
	}
	if (type >= EItemSubType::EItemSubType_yk_rune_begin && type <= EItemSubType::EItemSubType_yk_rune_end)
	{
		return EItemRuneType_YK;
	}
	return EItemRuneType_Limit;
}

void PackagePart::AddRuneSkill(const ItemItemCfgInfo *pItemCfg/*, EItemRuneType runeType*/)
{
	//EEquipPos equip_pos = (runeType == EItemRuneType_DW) ? EEquipPos_weapon : EEquipPos_clothes;
	//CItemBase *pEquip = GetEquip(equip_pos);
	//if (nullptr == pEquip)		return;

	const VEC_INT32 *pvecPara = g_GetItemCfgMgr()->GetItemFuncParamCfg(pItemCfg->id);
	if (nullptr == pvecPara)
	{
		LogErrFmtPrint("[logic] PackagePart::AddRuneSkill...nullptr == pvecPara..  itemid:%u,functionType:%d ", pItemCfg->id, pItemCfg->functionType);
		return;
	}
	if (pvecPara->size() < 2)
	{
		LogErrFmtPrint("[logic] PackagePart::AddRuneSkill...rune functionvalue param error..  itemid:%u,functionvalue:%s ", pItemCfg->id, pItemCfg->functionValue.c_str());
		return;
	}
	uint32_t nSkillID = pvecPara->at(0);
	uint32_t nSkillLev = pvecPara->at(1);
	const SkillSkillCfgInfo *pSkillCfg = g_GetSkillSkillCfgTable()->GetSkillSkillCfgInfo(nSkillID);
	if (nullptr == pSkillCfg)
	{
		LogErrFmtPrint("[logic] PackagePart::AddRuneSkill...nullptr == pSkillCfg..  itemid:%u,nSkillID:%u ", pItemCfg->id, nSkillID);
		return;
	}
	SkillPart *pSkillPart =dynamic_cast<SkillPart*>(m_pMaster->GetPart(PART_SKILL));
	if (nullptr == pSkillPart)		return;

	pSkillPart->AddSkill(pSkillCfg->skillID, nSkillLev, pSkillCfg->cd, 0, true, true, enSkillSaveType_SaveDB);
}

void PackagePart::AddRuneSkill(uint32_t runeItemId)
{
	//if (pos != EEquipPos_weapon && pos != EEquipPos_clothes)	return;
	//EItemRuneType runeType = (pos == EEquipPos_weapon) ? EItemRuneType_DW : EItemRuneType_YK;

	//uint32_t runeItemId = m_nRuneItemId[runeType];
	if (runeItemId <= 0)	return;

	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(runeItemId);
	if (nullptr == pItemCfg)
	{
		LogErrFmtPrint("[logic] PackagePart::AddRuneSkill...nullptr == pItemCfg  itemid:%u ", runeItemId);
		return;
	}
	AddRuneSkill(pItemCfg);
}

void PackagePart::RemoveRuneSkill(uint32_t item_id)
{
	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(item_id);
	if (nullptr == pItemCfg)
	{
		LogErrFmtPrint("[logic] PackagePart::RemoveRuneSkill...nullptr == pItemCfg  itemid:%u ", item_id);
		return;
	}
	/*if (pItemCfg->subType < (int32_t)EItemSubType::EItemSubType_holystone_begin || pItemCfg->subType >(int32_t)EItemSubType::EItemSubType_holystone_end)
	{
		LogErrFmtPrint("[logic] PackagePart::RemoveRuneSkill...item is not rune..  itemid:%u,subtype:%d ", item_id, pItemCfg->subType);
		return;
	}
	if (pItemCfg->functionType != (int32_t)EItemFuncType::EItemFuncType_AttachSkill && pItemCfg->functionType != (int32_t)EItemFuncType::EItemFuncType_passiveSkill)
	{
		LogErrFmtPrint("[logic] PackagePart::RemoveRuneSkill...rune functiontype error..  itemid:%u,functionType:%d ", item_id, pItemCfg->functionType);
		return;
	}*/
	if (pItemCfg->subType < (int32_t)EItemSubType::EItemSubType_dy_rune_begin || pItemCfg->subType >(int32_t)EItemSubType::EItemSubType_yk_rune_end)
	{
		//非符文(神印石)
		LogErrFmtPrint("[logic] PackagePart::RemoveRuneSkill...item is not rune..  itemid:%u,subtype:%d ", item_id, pItemCfg->subType);
		return;
	}
	const VEC_INT32 *pvecPara = g_GetItemCfgMgr()->GetItemFuncParamCfg(pItemCfg->id);
	if (nullptr == pvecPara)
	{
		LogErrFmtPrint("[logic] PackagePart::RemoveRuneSkill...nullptr == pvecPara..  itemid:%u,functionType:%d ", item_id, pItemCfg->functionType);
		return;
	}
	if (pvecPara->size() < 2)
	{
		LogErrFmtPrint("[logic] PackagePart::RemoveRuneSkill...rune functionvalue param error..  itemid:%u,functionvalue:%s ", item_id, pItemCfg->functionValue.c_str());
		return;
	}
	uint32_t nSkillID = pvecPara->at(0);
	const SkillSkillCfgInfo *pSkillCfg = g_GetSkillSkillCfgTable()->GetSkillSkillCfgInfo(nSkillID);
	if (nullptr == pSkillCfg)
	{
		LogErrFmtPrint("[logic] PackagePart::RemoveRuneSkill...nullptr == pSkillCfg..  itemid:%u,nSkillID:%u ", item_id, nSkillID);
		return;
	}
	SkillPart *pSkillPart = dynamic_cast<SkillPart*>(m_pMaster->GetPart(PART_SKILL));
	if (nullptr != pSkillPart)
	{
		pSkillPart->RemoveSkill(pSkillCfg->skillID);
	}
}

void PackagePart::GetEquipInfo(::google::protobuf::RepeatedPtrField< ::ProtoBuf::ItemProtoInfo >& equipInfo)
{
	for (uint32_t i = 0; i < m_vecPlayerEquip.size(); i++)
	{
		if (nullptr != m_vecPlayerEquip[i])
		{
			ItemProtoInfo *protoItem = equipInfo.Add();
			SetUpdateItemInfo(m_vecPlayerEquip[i], protoItem);
		}
	}
}

void PackagePart::GetEquipSlotInfo(::google::protobuf::RepeatedPtrField< ::ProtoBuf::EquipSlotProto >& equipSlot)
{
	for (uint8_t i = EEquipPos_none + 1; i < EEquipPos_limit; ++i)
	{
		EquipSlot &slot = m_vecEquipSlot[i];
		EquipSlotProto *protoSlot = equipSlot.Add();
		SetEquipSlotInfo(slot, protoSlot);
	}
}

void PackagePart::GetFacade(CharFacadeProto& facadeProto)
{
	facadeProto.set_weapon_id(m_equipFacade.sFacade.weaponId);
	facadeProto.set_clothes_id(m_equipFacade.sFacade.clothesId);
	facadeProto.set_wing_id(m_equipFacade.sFacade.wingId);
	facadeProto.set_fashion_id(m_equipFacade.sFacade.fashionId);
	facadeProto.set_rune_dw_id(m_equipFacade.sFacade.runeDWId);
	facadeProto.set_rune_yk_id(m_equipFacade.sFacade.runeYKId);
	facadeProto.set_weapon_effect_id(m_equipFacade.sFacade.wEffectid);
	facadeProto.set_body_effect_id(m_equipFacade.sFacade.bEffectid);
}

void PackagePart::UpdateFacade()
{
	CEquip *pClothes = GetEquip(EEquipPos_clothes);
	CEquip *pWeapon = GetEquip(EEquipPos_weapon);
	CEquip *pWing = GetEquip(EEquipPos_wing);
	CEquip *pGodClothes = GetEquip(EEquipPos_clothes, EEquipType_GodEquip);
	CEquip *pGodWeapon = GetEquip(EEquipPos_weapon, EEquipType_GodEquip);
	if (nullptr != pClothes)
		m_equipFacade.clothesId = pClothes->GetItemID();
	if (nullptr != pWeapon)
	{
		m_equipFacade.weaponId = pWeapon->GetItemID();
	}
		
	if (nullptr != pWing)
		m_equipFacade.wingId = pWing->GetItemID();
	if (nullptr != pGodClothes)
		m_equipFacade.godClothesId = pGodClothes->GetItemID();
	if (nullptr != pGodWeapon)
		m_equipFacade.godWeaponId = pGodWeapon->GetItemID();

	SET_UINT32 lel5Set;
	SET_UINT32 lel10Set;
	SET_UINT32 lel15Set;
	m_equipFacade.wEffectid = EeEquipEffectTypeID_None;
	m_equipFacade.bEffectid = EBodyEffectTypeID_None;
	for (uint8_t i = EEquipPos_none + 1; i <= EEquipPos_talisman; ++i)
	{
		CEquip *pEquip = GetEquip(i);
		if (nullptr == pEquip)
			continue;

		if (EEquipPos_weapon == i)
		{
			m_equipFacade.wEffectid = pWeapon->GetRefineLev() >= REFINE_EFFECT_LEVEL_TOP ? EeEquipEffectTypeID_C : (pWeapon->GetRefineLev() >= REFINE_EFFECT_LEVEL_MID ? EeEquipEffectTypeID_B : (pWeapon->GetRefineLev() >= REFINE_EFFECT_LEVEL_LOW ? EeEquipEffectTypeID_A : EeEquipEffectTypeID_None));
			continue;
		}

		if (pEquip->GetRefineLev() >= REFINE_EFFECT_LEVEL_LOW)
			lel5Set.insert(pEquip->GetItemID());
		if (pEquip->GetRefineLev() >= REFINE_EFFECT_LEVEL_MID)
			lel10Set.insert(pEquip->GetItemID());
		if (pEquip->GetRefineLev() >= REFINE_EFFECT_LEVEL_TOP)
			lel15Set.insert(pEquip->GetItemID());
	}

	EBodyEffectTypeID b5 = lel5Set.size() >= REFINE_EFFECT_NUM_TOP ? EBodyEffectTypeID_C : (lel5Set.size() >= REFINE_EFFECT_NUM_MID ? EBodyEffectTypeID_B : (lel5Set.size() >= REFINE_EFFECT_NUM_LOW ? EBodyEffectTypeID_A : EBodyEffectTypeID_None));
	EBodyEffectTypeID b10 = lel10Set.size() >= REFINE_EFFECT_NUM_TOP ? EBodyEffectTypeID_F : (lel10Set.size() >= REFINE_EFFECT_NUM_MID ? EBodyEffectTypeID_E : (lel10Set.size() >= REFINE_EFFECT_NUM_LOW ? EBodyEffectTypeID_D : EBodyEffectTypeID_None));
	EBodyEffectTypeID b15 = lel15Set.size() >= REFINE_EFFECT_NUM_TOP ? EBodyEffectTypeID_I : (lel15Set.size() >= REFINE_EFFECT_NUM_MID ? EBodyEffectTypeID_H : (lel15Set.size() >= REFINE_EFFECT_NUM_LOW ? EBodyEffectTypeID_G : EBodyEffectTypeID_None));
	EBodyEffectTypeID bodyEffectId = max(max(b5, b10), b15);
	m_equipFacade.bEffectid = bodyEffectId;

	if (m_equipFacade.showType == EEquipType_Equip)
	{
		m_equipFacade.sFacade.clothesId = m_equipFacade.clothesId;
		m_equipFacade.sFacade.weaponId = m_equipFacade.weaponId;
		m_equipFacade.sFacade.wingId = m_equipFacade.wingId;
		m_equipFacade.sFacade.runeDWId = m_equipFacade.runeDWId;
		m_equipFacade.sFacade.runeYKId = m_equipFacade.runeYKId;
		m_equipFacade.sFacade.wEffectid = m_equipFacade.wEffectid;
		m_equipFacade.sFacade.bEffectid = m_equipFacade.bEffectid;
	}
	else if (m_equipFacade.showType == EEquipType_GodEquip)
	{
		m_equipFacade.sFacade.weaponId = m_equipFacade.godWeaponId > 0 ? m_equipFacade.godWeaponId : m_equipFacade.weaponId;
		m_equipFacade.sFacade.runeDWId = m_equipFacade.godWeaponId > 0 ? 0 : m_equipFacade.runeDWId;
		m_equipFacade.sFacade.clothesId = m_equipFacade.godClothesId > 0 ? m_equipFacade.godClothesId : m_equipFacade.clothesId;
		m_equipFacade.sFacade.runeYKId = m_equipFacade.godClothesId > 0 ? 0 : m_equipFacade.runeYKId;
		m_equipFacade.sFacade.wingId = m_equipFacade.wingId;
		m_equipFacade.sFacade.wEffectid = m_equipFacade.godWeaponId <= 0 ? m_equipFacade.wEffectid : EeEquipEffectTypeID_None;
		m_equipFacade.sFacade.bEffectid = m_equipFacade.godClothesId <= 0 ? m_equipFacade.bEffectid : EBodyEffectTypeID_None;
	}
	else
	{
		m_equipFacade.sFacade.fashionId = m_equipFacade.fashionId;
		m_equipFacade.sFacade.clothesId = m_equipFacade.fashionId > 0 ? 0 : m_equipFacade.clothesId;
		m_equipFacade.sFacade.runeYKId = m_equipFacade.fashionId > 0 ? 0 : m_equipFacade.runeYKId;
		m_equipFacade.sFacade.weaponId = m_equipFacade.weaponId;
		m_equipFacade.sFacade.wingId = m_equipFacade.wingId;
		m_equipFacade.sFacade.runeDWId = m_equipFacade.runeDWId;
		m_equipFacade.sFacade.wEffectid = m_equipFacade.wEffectid;
		m_equipFacade.sFacade.bEffectid = m_equipFacade.fashionId <= 0 ? m_equipFacade.bEffectid : EBodyEffectTypeID_None;
	}
}

void PackagePart::GetRuneItemId(uint32_t &dwRuneItemId, uint32_t &ykRuneItemId)
{
	CItemBase *pWeapon = GetEquip(EEquipPos_weapon);
	if (pWeapon)
		dwRuneItemId = pWeapon->GetHoly();
	CItemBase *pClothes = GetEquip(EEquipPos_clothes);
	if (pClothes)
		ykRuneItemId = pClothes->GetHoly();
}

bool PackagePart::SetTreasureArea(int32_t item_idx, uint32_t areaId)
{
	CItemBase *pItem = GetItemByIndex(item_idx);
	if (pItem && pItem->GetAreaId() > 0)
	{
		pItem->SetAreaId(areaId);
		PackageUpdateRet update;
		ItemProtoInfo *protoItem = update.add_item_list();
		SetUpdateItemInfo(pItem, protoItem);
		UpdatePackageInfo(update);
		return true;
	}
	return false;
}

void PackagePart::GetSellItems(PlayerSellBackItem& sellItem)
{
	for (std::deque<CItemBase*>::iterator iter = m_dequeRebuyItem.begin(); iter != m_dequeRebuyItem.end(); ++iter)
	{
		ItemProtoInfo *itemProto = sellItem.add_item_lst();
		if (nullptr != itemProto)
		{
			g_GetItemMgr()->SetItemProtoInfo(*iter, itemProto);
		}
		else
		{
			LogErrFmtPrint("[logic] PackagePart::GetSellItems nullptr == itemProto....fail");
		}
	}
}

void PackagePart::SetSellItems(const PlayerSellBackItem& sellItem)
{
	for (int32_t i = 0; i != sellItem.item_lst_size(); ++i)
	{
		uint8_t byType = EItemType_common;
		const ItemProtoInfo &itemProto = sellItem.item_lst(i);
		const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(itemProto.item_id());
		if (nullptr == pItemCfg)
		{
			const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(itemProto.item_id());
			if (nullptr == pEquipCfg)
			{
				LogErrFmtPrint("[logic] PackagePart::SetSellItems..nullptr == pEquipCfg....itemid:%u ", itemProto.item_id());
				continue;
			}
			byType = EItemType_equip;
		}
		CItemBase *pItem = g_GetItemMgr()->MakeItemObj(byType);
		if (nullptr != pItem)
		{
			if (!pItem->SetItemProto(itemProto))
			{
				LogErrFmtPrint("[logic] PackagePart::SetSellItems 33, SetItemProto failed....index:%d, item_id:%u,num:%d,bind:%d..", itemProto.index(), itemProto.item_id(), itemProto.item_num(), itemProto.bind());
				g_GetItemMgr()->FreeItemObj(pItem);
			}
			else
			{
				//m_dequeRebuyItem.push_front(pItem);
				m_dequeRebuyItem.push_back(pItem);
			}
		}
		else
		{
			MMOLOG_FMT_ERROR("[logic] PackagePart::SetSellItems  , nullptr == pItem...");
		}
	}
}

int32_t PackagePart::ActiveFashion(int32_t nItemID, uint32_t fashionId)
{
	const EquipFashionCfgInfo *pFashionCfg = g_GetEquipFashionCfgTable()->GetEquipFashionCfgInfo(fashionId);
	if (nullptr == pFashionCfg)
	{
		return RET_CONFIG_ERROR;
	}
	size_t size = pFashionCfg->vecEquipFashionItemCfg.size();
	if (size <= 0 || size != pFashionCfg->vecEquipFashionDaysCfg.size())
	{
		return RET_CONFIG_ERROR;
	}
	int32_t days = 0;
	bool exist = false;
	for (size_t i = 0; i != size; i++)
	{
		if (nItemID == pFashionCfg->vecEquipFashionItemCfg.at(i).ID)
		{
			days = pFashionCfg->vecEquipFashionDaysCfg.at(i).time;
			exist = true;
			break;
		}
	}
	if (!exist)
	{
		return RET_CONFIG_ERROR;
	}

	exist = false;
	for (VEC_PLAYER_FASHION::iterator it = m_vecPlayerFashion.begin(); it != m_vecPlayerFashion.end(); it++)
	{
		CFashion &fashion = *it;
		if (fashionId == fashion.fashionId)
		{
			if (-10000 == fashion.leftMin)
			{
				return RET_PACKAGE_USE_FASHION_ERROR;
			}
			fashion.leftMin = (days == 0) ? -10000 : (fashion.leftMin + days * s_day_total_min);
			exist = true;
			break;
		}
	}

	if (!exist)
	{
		CFashion fashion;
		fashion.fashionId = fashionId;
		fashion.leftMin = (days == 0) ? -10000 : days * s_day_total_min;
		m_vecPlayerFashion.push_back(fashion);

		if (days <= 0)
		{
			FashionActiveEvent fashionEvent;
			g_GetEvent()->FireExecute(EVENT_FASHION_ACTIVE, m_pMaster->GetCid(), CREATURE_PLAYER, (FashionActiveEvent*)&fashionEvent, sizeof(FashionActiveEvent));
		}
	}

	for (VEC_PLAYER_FASHION::iterator it = m_vecPlayerFashion.begin(); it != m_vecPlayerFashion.end(); it++)
	{
		CFashion &fashion = *it;
		if (fashionId == fashion.fashionId)
		{
			NotifyFashion(fashion, exist ? FashionOperateType_Time : FashionOperateType_Add);
		}
	}

	return RET_SUCCESS;
}

void PackagePart::NotifyFashion(CFashion &fashion, FashionOperateType operate/*int8_t operate*/)
{
	FashionChangeNotify notify;
	notify.set_operate(operate);
	FashionProtoInfo *fashionProto = notify.mutable_fashion();
	fashionProto->set_fashion_id(fashion.fashionId);
	fashionProto->set_left_time((fashion.leftMin >= 0) ? fashion.leftMin * 60 : -10000);
	fashionProto->set_is_dress(fashion.isDress);
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_FASHION_CHANGE, &notify);
}

void PackagePart::UpdateFashion()
{
	for (VEC_PLAYER_FASHION::iterator it = m_vecPlayerFashion.begin(); it != m_vecPlayerFashion.end();)
	{
		if ((*it).leftMin == -10000)
		{
			it++;
			continue;
		}
		if ((*it).leftMin > 0)
		{
			(*it).leftMin--;
		}
		if ((*it).leftMin <= 0)
		{
			NotifyFashion(*it, FashionOperateType_Del);
			if ((*it).isDress)	
			{
				m_equipFacade.fashionId = 0;
				FacadeChange();
			}
			it = m_vecPlayerFashion.erase(it);
			continue;
		}
		it++;
	}
}

void PackagePart::DressFashion(const char *data, uint32_t len)
{
	FashionDressReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] FashionDressReq parse failed...");
		return;
	}
	uint32_t fashionId = req.fashion_id();

	FashionDressRsp rsp;
	rsp.set_retcode(RET_SUCCESS);
	rsp.set_fashion_id(fashionId);
	bool exist = false;

	uint32_t curFashionId = 0;	//当前穿戴时装
	for (VEC_PLAYER_FASHION::iterator it = m_vecPlayerFashion.begin(); it != m_vecPlayerFashion.end(); it++)
	{
		CFashion &fashion = *it;
		if (fashion.isDress)
		{
			curFashionId = fashion.fashionId;
			if (fashionId == curFashionId)
			{
				rsp.set_retcode(RET_FAIL);
				m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_FASHION_DRESS, &rsp);
				return;
			}
		}
		if (fashionId == fashion.fashionId)
		{
			exist = true;
		}
	}

	if (!exist)
	{
		rsp.set_retcode(RET_PACKAGE_FASHION_NOT_EXIST);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_FASHION_DRESS, &rsp);
		return;
	}

	for (VEC_PLAYER_FASHION::iterator it = m_vecPlayerFashion.begin(); it != m_vecPlayerFashion.end(); it++)
	{
		CFashion &fashion = *it;
		if (curFashionId == fashion.fashionId)
		{
			fashion.isDress = false;
		}
		if (fashionId == fashion.fashionId)
		{
			fashion.isDress = true;
			m_equipFacade.fashionId = fashionId;
			FacadeChange();
		}
	}

	CalcEquipAttr();
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_FASHION_DRESS, &rsp);
}

bool PackagePart::IsFashionDress(uint32_t fashionId)
{
	for (VEC_PLAYER_FASHION::iterator it = m_vecPlayerFashion.begin(); it != m_vecPlayerFashion.end(); it++)
	{
		CFashion &fashion = *it;
		if (fashionId == fashion.fashionId && fashion.isDress)
			return true;
	}
	return false;
}

void PackagePart::UnDressFashion(const char *data, uint32_t len)
{
	FashionUnDressReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] FashionUnDressReq parse failed...");
		return;
	}
	uint32_t fashionId = req.fashion_id();

	FashionUnDressRsp rsp;
	rsp.set_retcode(RET_SUCCESS);
	rsp.set_fashion_id(fashionId);
	bool exist = false;

	for (VEC_PLAYER_FASHION::iterator it = m_vecPlayerFashion.begin(); it != m_vecPlayerFashion.end(); it++)
	{
		CFashion &fashion = *it;
		if (fashionId != fashion.fashionId)
		{
			continue;
		}
		if (!fashion.isDress)
		{
			rsp.set_retcode(RET_FAIL);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_FASHION_DRESS, &rsp);
			return;
		}
		exist = true;
		fashion.isDress = false;
		m_equipFacade.fashionId = 0;
		FacadeChange();
	}

	if (!exist)
	{
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_FASHION_UNDRESS, &rsp);
		return;
	}

	CalcEquipAttr();
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_FASHION_UNDRESS, &rsp);
}

void PackagePart::UpdateGodEquip()
{
	//LogDebugFmtPrint("[logic] ++++++++++++++++++UpdateGodEquip+++++++++++++++++++++++++++");
	bool godEquipUpdate = false;
	PlayerEquipUpdateRet equip_update_ret;
	bool facadeeUpdate = false;
	int64_t nowTick = g_GetGlobalServerTime()->UnixSec();

	//穿戴的神装
	VEC_PLAYER_EQUIP::iterator iterGodEquip = m_vecPlayerGodEquip.begin();
	for (; iterGodEquip != m_vecPlayerGodEquip.end(); ++iterGodEquip)
	{
		CEquip *pGodEquip = (*iterGodEquip);
		if (nullptr == pGodEquip)
			continue;
		
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pGodEquip->GetItemID());
		if (nullptr == pEquipCfg || pEquipCfg->gold != 2)
			continue;

		if (pGodEquip->GetEndTick() == -10000)	//永久神装
		{
			continue;
		}			
		//神装失效
		if (nowTick >= pGodEquip->GetEndTick())
		{
			if (EEquipPos_weapon == pGodEquip->GetIndex())
			{
				facadeeUpdate = true;
				m_equipFacade.godWeaponId = 0;
			}
			if (EEquipPos_clothes == pGodEquip->GetIndex())
			{
				facadeeUpdate = true;
				m_equipFacade.godClothesId = 0;
			}
			AddPlayerEquipUpdateInfo(pGodEquip, equip_update_ret, true);
			SetEquipByIndex(pGodEquip->GetIndex(), nullptr, EEquipType_GodEquip);
			g_GetItemMgr()->FreeItemObj(pGodEquip);
			godEquipUpdate = true;
		}
	}

	//背包神装
	MAP_UINT16_INT32 mapDelItem;
	mapDelItem.clear();
	VEC_PACKAGE_ITEM::iterator iter = m_vecItems.begin();
	for (; iter != m_vecItems.end(); ++iter)
	{
		CItemBase *pItemBase = (*iter);
		if (nullptr == pItemBase || pItemBase->GetType() != EItemType_equip)
			continue;

		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pItemBase->GetItemID());
		if (nullptr == pEquipCfg || pEquipCfg->gold != 2)
			continue;

		if (pItemBase->GetEndTick() == -10000)	//永久神装
			continue;
		//神装失效
		if (nowTick >= pItemBase->GetEndTick())
		{
			mapDelItem[pItemBase->GetIndex()] = pItemBase->GetNum();
		}
	}

	if (mapDelItem.size() > 0)
	{
		SItemSourceParam sourceParam;
		sourceParam.source = S_PACKAGE;
		RemoveItem(mapDelItem, sourceParam);
	}	

	//仓库神装
	MAP_UINT16_INT32 mapDelStrogeItem;
	mapDelStrogeItem.clear();
	VEC_PACKAGE_ITEM::iterator iterStorage = m_vecStorage.begin();
	for (; iterStorage != m_vecStorage.end(); ++iterStorage)
	{
		CItemBase *pItemBase = (*iterStorage);
		if (nullptr == pItemBase || pItemBase->GetType() != EItemType_equip)
			continue;

		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pItemBase->GetItemID());
		if (nullptr == pEquipCfg || pEquipCfg->gold != 2)
			continue;

		if (pItemBase->GetEndTick() == -10000)	//永久神装
			continue;
		if (nowTick >= pItemBase->GetEndTick())
		{
			mapDelStrogeItem[pItemBase->GetIndex()] = pItemBase->GetNum();
		}
	}
	if (mapDelStrogeItem.size() > 0)
	{
		RemoveStorageItem(mapDelStrogeItem);
	}	

	if (godEquipUpdate)
	{
		equip_update_ret.set_equip_type(EEquipType_GodEquip);
		UpdateEquipInfo(equip_update_ret);
		CalcEquipAttr();
	}
	if (facadeeUpdate)
	{
		FacadeChange();
	}
}

void PackagePart::StarSoulMark(const char *data, uint32_t len)
{
	MarkStarSoulReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] MarkStarSoulReq parse failed...");
		return;
	}

	MarkStarSoulRsp rsp;
	rsp.set_retcode(RET_SUCCESS);

	//动态地图或副本不能标记
	/*if (m_pMaster->GetScene()->IsDynamic() || nullptr != g_GetDuplicateMgr()->GetDuplicate(m_pMaster->GetSceneId()))
	{
		rsp.set_retcode(RET_PACKAGE_MARK_FORDID);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STAR_SOUL_MARK, &rsp);
		return;
	}

	//一些静态活动地图不能标记
	if (IsForbidUse(m_pMaster->GetSceneId()))
	{
		rsp.set_retcode(RET_PACKAGE_MARK_FORDID);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STAR_SOUL_MARK, &rsp);
		return;
	}

	//遗失之城活动期间不能使用
	if (!g_GetGActivityMgr()->CanTransScene(dynamic_cast<Player*>(m_pMaster)))
	{
		rsp.set_retcode(RET_PACKAGE_MARK_FORDID);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STAR_SOUL_MARK, &rsp);
		return;
	}*/

	CItemBase *pItem = GetItemByIndex(req.item_idx());
	if (nullptr == pItem)
	{
		rsp.set_retcode(RET_PACKAGE_ITEM_NOT_EXITS);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STAR_SOUL_MARK, &rsp);
		return;
	}

	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItem->GetItemID());
	if (nullptr == pItemCfg)
	{
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STAR_SOUL_MARK, &rsp);
		return;
	}

	if (pItemCfg->subType == (int32_t)EItemSubType::EItemSubType_star_soul_paper)
	{
		pItem->GetMarkPos()->clear();
		CMarkPos mPos;
		mPos.mapId = m_pMaster->GetMapId();
		mPos.pos = m_pMaster->GetPos();
		pItem->GetMarkPos()->push_back(mPos);
	}
	else if (pItemCfg->subType == (int32_t)EItemSubType::EItemSubType_star_soul_reel)
	{
		if (req.pos_idx() > 0)
		{
			if (req.pos_idx() > (int32_t)pItem->GetMarkPos()->size())
			{
				rsp.set_retcode(RET_PACKAGE_MARK_COUNT_LIMIT);
				m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STAR_SOUL_MARK, &rsp);
				return;
			}
			CMarkPos &mPos = pItem->GetMarkPos()->at(req.pos_idx() - 1);
			mPos.mapId = m_pMaster->GetMapId();
			mPos.pos = m_pMaster->GetPos();
		}
		else
		{
			if (pItem->GetMarkPos()->size() >= PACKAGE_STAR_SOUL_MARK_NUM)
			{
				rsp.set_retcode(RET_PACKAGE_MARK_COUNT_LIMIT);
				m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STAR_SOUL_MARK, &rsp);
				return;
			}
			CMarkPos mPos;
			mPos.mapId = m_pMaster->GetMapId();
			mPos.pos = m_pMaster->GetPos();
			pItem->GetMarkPos()->push_back(mPos);
		}
	}
	else
	{
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STAR_SOUL_MARK, &rsp);
		return;
	}

	PackageUpdateRet update;
	ItemProtoInfo *protoItem = update.add_item_list();
	SetUpdateItemInfo(pItem, protoItem);
	UpdatePackageInfo(update);

	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STAR_SOUL_MARK, &rsp);
}

void PackagePart::StarSoulUse(CItemBase *pItem)
{
	pItem->SetUseTimes(pItem->GetUseTimes() + 1);
	if (pItem->GetUseTimes() >= pItem->GetConfigTimes())
	{
		SItemSourceParam sourceParam;
		sourceParam.source = S_USE_ITEM;
		RemoveItemByIndex(pItem->GetIndex(), 1, sourceParam);
	}
	else
	{
		PackageUpdateRet update;
		ItemProtoInfo *protoItem = update.add_item_list();
		SetUpdateItemInfo(pItem, protoItem);
		UpdatePackageInfo(update);
	}
}

void PackagePart::StarSoulResp(const char *data, uint32_t len)
{
	StarSoulSendReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] StarSoulSendReq parse failed...");
		return;
	}

	//遗失之城活动期间不能使用
	if (!g_GetGActivityMgr()->CanTransScene(dynamic_cast<Player*>(m_pMaster)))
	{
		StarSoulSendRsp rsp;
		rsp.set_retcode(RET_PACKAGE_ITEM_LOST_CITY_FORBID);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STAR_SOUL_RESP, &rsp);
		return;
	}

	ERetCode ret = RET_SUCCESS;
	if (!m_pMaster->CanTrans(ret, req.map_id(), req.map_id()))
	{
		StarSoulSendRsp rsp;
		rsp.set_retcode(ret);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STAR_SOUL_RESP, &rsp);
		return;
	}

	//动态地图或副本不能标记
	if (m_pMaster->GetScene()->IsDynamic() || nullptr != g_GetDuplicateMgr()->GetDuplicate(m_pMaster->GetSceneId()))
	{
		StarSoulSendRsp rsp;
		rsp.set_retcode(RET_PACKAGE_MARK_FORDID);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STAR_SOUL_RESP, &rsp);
		return;
	}

	//一些静态活动地图不能标记
	/*if (IsForbidUse(m_pMaster->GetSceneId()))
	{
		StarSoulSendRsp rsp;
		rsp.set_retcode(RET_PACKAGE_MARK_FORDID);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STAR_SOUL_RESP, &rsp);
		return;
	}*/

	STransParam transParam;
	transParam.srcMapId = m_pMaster->GetMapId();
	transParam.transType = ETransType_StarSoul;
	if (req.type() == 2)	//响应队长星魂号角
	{
		transParam.transType = ETransType_StarSoulRsp;

		Player *pPlayer = dynamic_cast<Player*>(m_pMaster);
		if (nullptr == pPlayer)	return;
		if (pPlayer->GetAttr(C_TEAM_ID) <= 0)
		{
			StarSoulSendRsp rsp;
			rsp.set_retcode(RET_TEAM_NO_EXIST);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STAR_SOUL_RESP, &rsp);
			return;
		}
		
		ProtoBuf::GWChatMsgReq g2wChatMsg;
		g2wChatMsg.set_chattype(CHAT_TYPE_TEAM);
		g2wChatMsg.set_fromid(m_pMaster->GetCid());
		ChatContentInfo *content = g2wChatMsg.add_chatcontent();
		char text[256] = { 0 };
		snprintf(text, sizeof(text), "队员%s已响应队长传送至集合位置", pPlayer->GetName().c_str());
		content->set_describes(text);
		g_GetLogicService()->SendDataToCenter(EMODULE_ID_CHAT, CENTER_SERVER_PROTOCOL_CHAT_REQ, &g2wChatMsg);
	}
	
	Point3<float> pos;
	pos.x = req.cur_pos().x();
	pos.y = req.cur_pos().y();
	pos.z = req.cur_pos().z();
	m_pMaster->TransScene(req.map_id(), pos, req.map_id(), transParam);
	LogDebugFmtPrint("[logic] PackagePart::StarSoulResp....cid:%lu, curscene:%u, curmapid:%u, dstmap:%u, pos:[%f,%f,%f] ", m_pMaster->GetCid(), m_pMaster->GetSceneId(), m_pMaster->GetMapId(), req.map_id(), pos.x, pos.y, pos.z);
	StarSoulSendRsp rsp;
	rsp.set_retcode(RET_SUCCESS);
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_STAR_SOUL_RESP, &rsp);
}

int32_t PackagePart::OnStarSoul(int16_t nIndex)
{
	CItemBase *pItem = GetItemByIndex(nIndex);
	if (nullptr == pItem)
	{
		return RET_PACKAGE_ITEM_NOT_EXITS;
	}

	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItem->GetItemID());
	if (nullptr == pItemCfg)
	{
		return RET_CONFIG_ERROR;
	}

	if (pItemCfg->subType <= (int32_t)EItemSubType::EItemSubType_star_soul_begin || pItemCfg->subType >= (int32_t)EItemSubType::EItemSubType_star_soul_end)
	{
		return RET_CONFIG_ERROR;
	}

	//动态地图、副本不能使用
	if (m_pMaster->GetScene()->IsDynamic() || nullptr != g_GetDuplicateMgr()->GetDuplicate(m_pMaster->GetSceneId()))
	{
		return RET_PACKAGE_USE_MAP_LIMIT;
	}

	//遗失之城活动期间不能使用
	if (!g_GetGActivityMgr()->CanTransScene(dynamic_cast<Player*>(m_pMaster)))
	{
		return RET_PACKAGE_ITEM_LOST_CITY_FORBID;
	}

	switch (pItemCfg->subType)
	{
	case (int32_t)EItemSubType::EItemSubType_star_soul_paper:
	{
		StarSoulUse(pItem);
	}
	break;
	case (int32_t)EItemSubType::EItemSubType_star_soul_reel:
	{
		StarSoulUse(pItem);
	}
	break;
	case (int32_t)EItemSubType::EItemSubType_star_soul_horn:
	{
		if (!m_pMaster->GetAttr(C_TEAM_LEADER_ID))
		{
			return RET_DUPLICATE_NOT_TEM_LEADER;
		}
		//StarSoulUse(pItem);
		GWTeamCallMembers callMembers;
		callMembers.set_itemidx(nIndex);
		callMembers.set_leaderid(m_pMaster->GetCid());
		callMembers.set_mapid(m_pMaster->GetMapId());
		Vector3PB *pos = callMembers.mutable_pos();
		pos->set_x(m_pMaster->GetPos().x);
		pos->set_y(m_pMaster->GetPos().y);
		pos->set_z(m_pMaster->GetPos().z);
		g_GetLogicService()->SendDataToCenter(EMODULE_ID_TEAM, LOGIC_TO_CENTER_CALL_TEAM_MEMBERS, &callMembers);
		return RET_PACKAGE_WAITING;
	}
	break;
	default:
		break;
	}
	return RET_SUCCESS;
}

void PackagePart::OnStarSoulRsp(int32_t ret, int16_t nIndex)
{
	PackageUseRet rsp;
	rsp.set_retcode(ret);
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_PACKAGE_USE, &rsp);

	if (RET_SUCCESS == ret)
	{
		CItemBase *pItem = GetItemByIndex(nIndex);
		if (nullptr == pItem)
			return;

		const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItem->GetItemID());
		if (nullptr == pItemCfg)
			return;

		if (pItemCfg->subType != (int32_t)EItemSubType::EItemSubType_star_soul_horn)
			return;

		StarSoulUse(pItem);
		Player *pPlayer = dynamic_cast<Player*>(m_pMaster);
		if (nullptr == pPlayer)
			return;

		ProtoBuf::GWChatMsgReq g2wChatMsg;
		g2wChatMsg.set_chattype(CHAT_TYPE_TEAM);
		g2wChatMsg.set_fromid(m_pMaster->GetCid());
		ChatContentInfo *content = g2wChatMsg.add_chatcontent();
		char text[256] = { 0 };
		snprintf(text, sizeof(text), "各队员注意，队长%s已发起集合，请在30秒响应队长传送集合！", pPlayer->GetName().c_str());
		content->set_describes(text);
		g_GetLogicService()->SendDataToCenter(EMODULE_ID_CHAT, CENTER_SERVER_PROTOCOL_CHAT_REQ, &g2wChatMsg);
	}
}

void PackagePart::RebuyBack(const char *data, uint32_t len)
{
	ReBuyBackReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] ReBuyBackReq parse failed...");
		return;
	}

	ReBuyBackRsp rsp;
	rsp.set_retcode(RET_SUCCESS);

	int32_t idx = req.item_idx();

	if (idx < 1 || idx > 25)
	{
		rsp.set_retcode(RET_PARMAR_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_REBUY_BACK, &rsp);
		return;
	}

	if ((int32_t)m_dequeRebuyItem.size() < idx)
	{
		rsp.set_retcode(RET_PACKAGE_ITEM_NOT_EXITS);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_REBUY_BACK, &rsp);
		return;
	}

	CItemBase* pItem = m_dequeRebuyItem[idx - 1];
	if (nullptr == pItem)
	{
		rsp.set_retcode(RET_PACKAGE_ITEM_NOT_EXITS);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_REBUY_BACK, &rsp);
		return;
	}

	//添加到背包 
	VEC_ITEM_PROTO_EX itemProtoVec;
	ItemProtoInfo itemProto;
	g_GetItemMgr()->SetItemProtoInfo(pItem, &itemProto);
	itemProtoVec.push_back(itemProto);
	SItemSourceParam sourceParam;
	sourceParam.source = S_ReBuy;
	if (!AddItem(itemProtoVec, sourceParam))
	{
		rsp.set_retcode(RET_PACKAGE_SPACE_NOT_ENOUGH);
		m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_REBUY_BACK, &rsp);
		return;
	}
	
	uint32_t nTotalMoney = 0;
	uint16_t nSellNum = pItem->GetNum();
	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(pItem->GetItemID());
	if (nullptr != pItemCfg)
	{
		nTotalMoney += pItemCfg->sellPrice * nSellNum;
	}
	else
	{
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pItem->GetItemID());
		if (nullptr == pEquipCfg)
		{
			rsp.set_retcode(RET_PACKAGE_ITEM_NOT_EXITS);
			m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_REBUY_BACK, &rsp);
			return;
		}
		nTotalMoney = pEquipCfg->sellPrice;
	}
	m_pMaster->AddSourceAttr(C_GOLD, -1 * (int64_t)nTotalMoney, true, S_PACKAGE);
	
	m_dequeRebuyItem.erase(m_dequeRebuyItem.begin() + idx - 1);
	for (std::deque<CItemBase*>::iterator iter = m_dequeRebuyItem.begin(); iter != m_dequeRebuyItem.end(); ++iter)
	{
		ItemProtoInfo *itemProto = rsp.add_item_list();
		if (nullptr != itemProto)
		{
			g_GetItemMgr()->SetItemProtoInfo(*iter, itemProto);
		}
		else
		{
			LogErrFmtPrint("[logic] PackagePart::UpdateBuyBack nullptr == itemProto....fail");
		}
	}
	m_pMaster->SendDataToClient(EMODULE_ID_PACKAGE, LOGIC_TO_CLIENT_REBUY_BACK, &rsp);
}

void PackagePart::DelGodEquip(const char *data, uint32_t len)
{
	DeleteGodEquip delGodEquip;
	if (!delGodEquip.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] delGodEquip parse failed...");
		return;
	}

	int32_t type = delGodEquip.type();
	int32_t index = delGodEquip.item_idx();
	int64_t curTime = (int64_t)g_GetGlobalServerTime()->UnixSec();
	if (1 == type)	//背包
	{
		CItemBase *pItem = GetItemByIndex(index);
		if (nullptr == pItem)	
			return;
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pItem->GetItemID());
		if (nullptr == pEquipCfg || pEquipCfg->gold != 2)
			return;
		if (pItem->GetEndTick() == -10000)	//永久神装
			return;
		if (curTime < pItem->GetEndTick())
		{
			return;
		}
		MAP_UINT16_INT32 mapDelItem;
		mapDelItem.clear();
		mapDelItem[pItem->GetIndex()] = pItem->GetNum();
		PackageUpdateRet update_ret;
		AddPackageUpdateInfo(pItem, update_ret, true);
		UpdatePackageInfo(update_ret);
		SItemSourceParam sourceParam;
		sourceParam.source = S_PACKAGE;
		RemoveItem(mapDelItem, sourceParam);
	}
	else if (2 == type)	//仓库
	{
		CItemBase *pItem = GetStorageItemByIndex(index);
		if (nullptr == pItem)
			return;
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pItem->GetItemID());
		if (nullptr == pEquipCfg || pEquipCfg->gold != 2)
			return;
		if (pItem->GetEndTick() == -10000)	//永久神装
			return;
		if (curTime < pItem->GetEndTick())
		{
			return;
		}
		MAP_UINT16_INT32 mapDelItem;
		mapDelItem.clear();
		mapDelItem[pItem->GetIndex()] = pItem->GetNum();
		StorageUpdateRsp protoStorageRet;
		AddStorageUpdateInfo(pItem, protoStorageRet);
		StorageUpdate(protoStorageRet);
		RemoveStorageItem(mapDelItem);
	}
	else if (3 == type)	//神装装备
	{
		CEquip *pEquip = GetEquip(index, EEquipType_GodEquip);
		if (nullptr == pEquip)
			return;
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(pEquip->GetItemID());
		if (nullptr == pEquipCfg || pEquipCfg->gold != 2)
			return;
		if (pEquip->GetEndTick() == -10000)	//永久神装
			return;
		if (curTime < pEquip->GetEndTick())
		{
			return;
		}
		PlayerEquipUpdateRet equip_update_ret;
		if (EEquipPos_weapon == pEquip->GetIndex())
		{
			m_equipFacade.godWeaponId = 0;
			FacadeChange();
		}
		if (EEquipPos_clothes == pEquip->GetIndex())
		{
			m_equipFacade.godClothesId = 0;
			FacadeChange();
		}
		AddPlayerEquipUpdateInfo(pEquip, equip_update_ret, true);
		UpdateEquipInfo(equip_update_ret);
		SetEquipByIndex(pEquip->GetIndex(), nullptr, EEquipType_GodEquip);
		g_GetItemMgr()->FreeItemObj(pEquip);
		CalcEquipAttr();
	}
	else
		LogErrFmtPrint("[logic] PackagePart::DelGodEquip....type error...type=%d", type);
}

void PackagePart::ItemLog(LogTid tid, MAP_UINT32_INT32 &items, uint32_t source)
{
	//因为背包和装备切换都是走的Item所以这里标注S_END该物品不数据产出
	if (source == (uint32_t)S_NONE || items.empty())
		return;

	Player* pPlayer = static_cast<Player*>(m_pMaster);
	if (NULL == pPlayer)
	{
		LogErrFmtPrint("PackagePart::ItemLog,  pPlayer == null");
		return;
	}

	MAP_UINT32_INT32::iterator iter = items.begin();
	MAP_UINT32_INT32::iterator iterEnd = items.end();
	rapidjson::Document doc;
	JsonObject obj(&doc);
	JsonArray ary(&doc);

	for (; iter != iterEnd; ++iter)
	{
		JsonObject itemObj(&doc);
		itemObj.AddUInt32("id", iter->first);
		itemObj.AddUInt32("Num", iter->second);
		ary.PushObject(itemObj);
	}
	obj.AddArray("items", ary);

	pPlayer->ItemLog(tid, obj, source);
}

void PackagePart::ItemLog(LogTid tid, MAP_UINT16_INT32 &items, uint32_t source)
{
	//因为背包和装备切换都是走的Item所以这里标注S_END该物品不数据产出
	if (source == (uint32_t)S_NONE || items.empty())
		return;

	Player* pPlayer = static_cast<Player*>(m_pMaster);
	if (NULL == pPlayer)
	{
		LogErrFmtPrint("PackagePart::ItemLog,  pPlayer == null");
		return;
	}

	MAP_UINT16_INT32::iterator iter = items.begin();
	MAP_UINT16_INT32::iterator iterEnd = items.end();
	rapidjson::Document doc;
	JsonObject obj(&doc);
	JsonArray ary(&doc);

	for (; iter != iterEnd; ++iter)
	{
		JsonObject itemObj(&doc);
		CItemBase *pItem = GetItemByIndex(iter->first);
		if (nullptr == pItem)
		{
			LogErrFmtPrint("Item Log  pItem == null , pItem:%d,  itemId:%d", pItem, iter->first);
			continue;
		}
		itemObj.AddUInt32("id", pItem->GetItemID());
		itemObj.AddUInt32("Num", pItem->GetNum());
		ary.PushObject(itemObj);
	}
	obj.AddArray("items", ary);

	pPlayer->ItemLog(tid, obj, source);
}
